Skip to content

Instantly share code, notes, and snippets.

@ccapndave
Created December 6, 2016 11:22
Show Gist options
  • Save ccapndave/7f20fce192eec9dd0882787c2c1b95fc to your computer and use it in GitHub Desktop.
Save ccapndave/7f20fce192eec9dd0882787c2c1b95fc to your computer and use it in GitHub Desktop.
{-| In your face, type system! This function allows some very un-Elmy run-type introspection on type parameters by hacking around
with toString, regular expressions and Json decoders.
For example, if you have a type:
type Literal
= MyDetails { age : Int, height : Int }
Then you could use this function to get the type parameter as a `Dict String Int` with:
typeParametersToDict Json.Decode.int <| MyDetails { age = 30, height = 158 }
Note that this will only work when there is a single type parameter which is a record, and all the elements of the record have to
be of the same type. You can choose the type using the decoder parameter, but probably only simple types will work (string, int,
float, boolean).
-}
typeParameterRecordToDict : Decoder b -> a -> Dict String b
typeParameterRecordToDict decoder typeLiteral =
typeLiteral
-- String ~~> turn the type into a String using the native toString implementation
|> toString
-- String ~~> Get rid of the name of the type, just leaving { a = "1", b = "2" } or similar
|> Regex.replace (Regex.AtMost 1) (regex "^\\w* ") (always "")
-- String ~~> Use a regexp to turn this into valid JSON by turning { a = "1" } into { "a": "1" }
|> Regex.replace Regex.All (regex "(\\w*) =")
(\{ submatches } ->
submatches
|> List.filterMap identity
|> List.head
|> Maybe.map (\id -> "\"" ++ id ++ "\"" ++ ":")
|> Maybe.withDefault "" -- this can't happen in valid JSON
)
-- String ~~> Use the dict decoder to turn this into a Dict of whatever Decoder we gave as a parameter
|> JD.decodeString (JD.dict decoder)
-- Dict String String ~~> Don't allow run-time errors! If something goes wrong with the decoding, default to an empty Dict
|> Result.withDefault Dict.empty
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment