Posix.IO

Create IO

The IO err ok type is very similar in concept to Task err ok. The first parameter is the error value, the second value is the "return" value of an IO-operation.

A program must have the type IO String (). The error parameter must have type String. This allows the runtime to print error message to std err in case of a problem.

type alias IO err ok =
Cont Proc err ok
return : a -> IO err a
fail : err -> IO err a
none : IO x ()
fromResult : Result err ok -> IO err ok

Basic IO

print : String -> IO x ()
printLn : String -> IO x ()
sleep : Float -> IO x ()

Sleep process execution in milliseconds.

exit : Int -> IO x ()

Exit to shell with a status code

Transforming IO

map : (a -> b) -> IO x a -> IO x b
andMap : IO x a -> IO x (a -> b) -> IO x b

Applicative

map2 : (a -> b -> c) -> IO x a -> IO x b -> IO x c
map2 fn a b =
    IO.return fn
        |> IO.andMap a
        |> IO.andMap b
andThen : (a -> IO x b) -> IO x a -> IO x b
and : IO x b -> IO x a -> IO x b

Instead of:

sleep 100
    |> andThen (\_ -> printLn "Hello")

and allows you to do:

sleep 100
    |> and (printLn "Hello")
combine : List (IO err ok) -> IO err (List ok)

Handle Errors

mapError : (x -> y) -> IO x a -> IO y a
recover : (err -> IO x ok) -> IO err ok -> IO x ok

Tasks

performTask : Task Never a -> IO x a

Perform a task

getTime : IO x Time.Posix
getTime =
    performTask Time.now
attemptTask : Task err ok -> IO err ok

Attempt a Task that can fail.

For example you can fetch data using the elm/http package.

import Http

fetch : IO String String
fetch =
    Http.riskyTask
        { method = "GET"
        , headers = []
        , url = "http://example.com"
        , body = Http.emptyBody
        , resolver = Http.stringResolver stringBody
        , timeout = Just 10
        }
        |> attemptTask

stringBody : Http.Response String -> Result String String
stringBody response =
    case response of
        Http.GoodStatus_ metaData body ->
            Ok body

        _ ->
            Err "Problem"

Javascript Interop

callJs : String -> List Value -> Decoder a -> IO x a

Call a synchronous function in Javascript land.

This works by sending out a message through a port. The Javascript implementation will then send the return value back through another port.

callJs <fn> <args> <result decoder>

Example

js/my-functions.js

module.exports = {
    addOne: function(num) {
        // sync example
        return num + 1;
    },
    sleep: function(delay) {
        // async example
        return new Promise(resolve => {
            setTimeout(resolve, delay);
        });
    },
}

src/MyModule.elm

addOne : Int -> IO x Int
addOne n =
    IO.callJs
        "addOne"
        [ Encode.int n
        ]
        Decode.int

sleep : Float -> IO x ()
sleep delay =
    IO.callJs
        "sleep"
        [ Encode.float delay
        ]
        (Decode.succeed ())

Run like this:

elm.cli run --ext js/my-functions.js src/MyModule.elm

Program

makeProgram : (Process -> IO String ()) -> PosixProgram

Used by elm-cli to wrap your program.

Create your own program by defining program in your module.

program : Process -> IO String ()
program process =
    printLn "Hello, world!"
type alias Process =
{ argv : List String
, pid : Int
, env : Dict String String
}
type alias PortIn msg =
PortIn msg
type alias PortOut msg =
PortOut msg