Skip to content

Instantly share code, notes, and snippets.

@ulve
Created December 29, 2017 11:08
Show Gist options
  • Save ulve/6c0bc81da762c04ae07691f428919c78 to your computer and use it in GitHub Desktop.
Save ulve/6c0bc81da762c04ae07691f428919c78 to your computer and use it in GitHub Desktop.
MonadReader in elm
type alias Config =
{ httpEndpoint : String
, portNumber : Int
}
type alias Person =
{ name : String
, address : String
}
getPersonName : Config -> String -> String
getPersonName config pnr =
personInfo config pnr |> .name
personInfo : Config -> String -> Person
personInfo config pnr =
-- use config to make wscall
Person config.httpEndpoint "Södra kungsgatan"
use : String
use =
let
c = Config "http://localhost" 8080
in
getPersonName c "123"
type Reader ctx a
= Reader (ctx -> a)
unit : a -> Reader any a
unit x =
Reader (\_ -> x)
runReader : Reader ctx a -> ctx -> a
runReader r ctx =
case r of
Reader f ->
f ctx
withContext : context -> Reader context a -> a
withContext =
flip runReader
andThen : Reader ctx a -> (a -> Reader ctx b) -> Reader ctx b
andThen reader bindFn =
Reader
(\ctx ->
let
a =
runReader reader ctx
newReader =
bindFn a
in
runReader newReader ctx
)
(>>=) : Reader ctx a -> (a -> Reader ctx b) -> Reader ctx b
(>>=) =
andThen
ask : Reader ctx ctx
ask =
Reader identity
getPersonNameM : String -> Reader Config String
getPersonNameM pnr =
-- does not know anything about the config
personInfoM pnr >>= (.name >> unit)
personInfoM : String -> Reader Config Person
personInfoM pnr =
ask >>= \c -> unit (Person ("Got endpoint " ++ c.httpEndpoint) "Södra kungs")
useM : String
useM =
let
r = getPersonNameM "123"
c = Config "endpoint" 8080
in
runReader r c
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment