lucamug/elm-exercises/2.0.6

Exercises

Ellie Elements

These are the elements used inside Ellie to build an exercise.

{ tests : List Test
, portLocalStoragePop : (String -> Msg ()) -> Sub (Msg ())
, portLocalStoragePush : String -> Cmd (Msg ())
}
-> Program Flags (Model ()) (Msg ())
import Exercises exposing (..)




-- Write a function `last` that returns
-- the last element of a list.
--
last : List a -> Maybe a
last xs =
    -- Your implementation goes here
    Nothing


tests : List Test
tests =
    -- Your implementation should pass
    -- these tests
    [ last [ 1, 2, 3, 4 ] == Just 4
    , last [ 1 ] == Just 1
    , last [] == Nothing
    , last [ 'a', 'b', 'c' ] == Just 'c'
    ]


main : Program Flags (Model ()) (Msg ())
main =
    exercise
        { tests = tests
        , portLocalStoragePop = portLocalStoragePop
        , portLocalStoragePush = portLocalStoragePush
        }


port portLocalStoragePop : (String -> msg) -> Sub msg


port portLocalStoragePush : String -> Cmd msg
{ tests : List Test
, portLocalStoragePop : (String -> Msg ()) -> Sub (Msg ())
, portLocalStoragePush : String -> Cmd (Msg ())
, view : Element ()
}
-> Program Flags (Model ()) (Msg ())
{ init : ( modelExercise, Cmd msgExercise )
, view : Maybe (modelExercise -> Element msgExercise)
, update :
msgExercise -> modelExercise -> ( modelExercise, Cmd msgExercise )
, subscriptions : modelExercise -> Sub msgExercise
, tests : modelExercise -> List Test
, portLocalStoragePop :
(String -> Msg msgExercise) -> Sub (Msg msgExercise)
, portLocalStoragePush : String -> Cmd (Msg msgExercise)
}
-> Program Flags (Model modelExercise) (Msg msgExercise)

If the exercise require The Elm Architecure and tests need to access the Model, it is possible to use exerciseWithTea instead of the simpler exercise. It is the analogue of Browser.element but without flags.

import Exercises exposing (..)




-- Write a function `last` that returns
-- the last element of a list.
--
last : List a -> Maybe a
last xs =
    -- Your implementation goes here
    Nothing


main : Program Flags (Model ModelExercise) (Msg MsgExercise)
main =
    exerciseWithTea
        { tests =
            -- Your implementation should pass
            -- these tests
            \model ->
                [ last [ 1, 2, 3, 4 ] == Just 4
                , last [ 1 ] == Just 1
                , last [] == Nothing
                , last [ 'a', 'b', 'c' ] == Just 'c'
                ]
        , init = init
        , view = view
        , update = update
        , subscriptions = subscriptions
        }


-- Following the definitions of
-- init, view, update, and subscriptions.
type alias Flags =
Flags

Flags are used to pass details about the exercises to the page.

They can be either loaded from external scripts, like in this example:

(HTML)

<script src="https://elm-exercises.netlify.app/js/index.js"></script>
<script src="https://elm-exercises.netlify.app/js/001.js"></script>
<script src="https://elm-exercises.netlify.app/start.js"></script>

You can check the forrmat of the data in these files as reference:

Or they can be hard coded, like in this example (See ExerciseData for a detailed explanation of the fields):

(JavaScript)

var app = Elm.Main.init({
  node: document.getElementById("elm"),
  flags: {
    index: JSON.stringify([]),
    exercise: JSON.stringify(
      { id: 1            // Exercise ID
      , title: ""        // Title of the exercise
      , difficulty: Easy // Easy | Medium | Hard | Undefined
      , problem: ""      // Details of the problem to be solved
      , tests: []        // List of tests
      , hints: []        // List of hints
      , solutions: []    // List of solutions
      , ellie: ""        // Ellie ID
      }
    )
  }
});
type alias Model modelExercise =
Model modelExercise

Internal. Exposed to be used in type signatures

type alias Msg msgExercise =
Msg msgExercise

Internal. Exposed to be used in type signatures

ExerciseData

type alias ExerciseData =
ExerciseData
type alias Difficulty =
Difficulty
{ easy : Difficulty
, hard : Difficulty
, medium : Difficulty
, undefined : Difficulty
}

Helpers

attrsButton : List (Attribute msg)

Tests

These are the same tests of elm-explorations/test. Refer to that package for the documentation.

type alias Test =
Expectation

Rename Expectation to Test as they can be run immediately in this context

equal : a -> a -> Test
notEqual : a -> a -> Test
all : List (subject -> Test) -> subject -> Test
lessThan : comparable -> comparable -> Test
atMost : comparable -> comparable -> Test
greaterThan : comparable -> comparable -> Test
atLeast : comparable -> comparable -> Test
FloatingPointTolerance
within : FloatingPointTolerance -> Float -> Float -> Test
notWithin : FloatingPointTolerance -> Float -> Float -> Test
true : String -> Bool -> Test
false : String -> Bool -> Test
ok : Result a b -> Test
err : Result a b -> Test
equalLists : List a -> List a -> Test
equalDicts : Dict comparable a -> Dict comparable a -> Test
equalSets : Set comparable -> Set comparable -> Test
pass : Test
fail : String -> Test
onFail : String -> Test -> Test

For internal use

TEA modelExercise msgExercise
-> Msg msgExercise
-> Model modelExercise
-> ( Model modelExercise, Cmd (Msg msgExercise) )
TEA modelExercise msgExercise
-> Model modelExercise
-> Element (Msg msgExercise)
viewElementAttrs : Model modelExercise -> List (Attribute (Msg msgExercise))
TEA modelExercise msgExercise
-> Flags
-> ( Model modelExercise, Cmd (Msg msgExercise) )
type alias TEA modelExercise msgExercise =
TEA modelExercise msgExercise
type alias Index =
Index

Codecs

codecIndex : Codec Index
codecExerciseData : Codec ExerciseData