-
Notifications
You must be signed in to change notification settings - Fork 8
Records
Problem 1
The trick is to define an extensible type:
takerVariant : { whole | id : Int } -> Int
takerVariant record =
record.idmakerVariant is impossible. It creates a record with a name field, but taker requires that its parameter have exactly and only an Int id. (I suppose makerVariant could throw away its argument and just produce {id = 3}, but that seems excessively pointless for a function that takes a name as an argument.)
Problem 2
Without a type annotation, Elm calculates this type for setName:
<function> : a -> { c | name : b } -> { c | name : a }I'd forgotten that the { record | ... } notation can change not
only a field's value but also its type. That is, it is allowed to take
a record with a name of type b and produce a record whose name type is now a.
Weird.
The following type annotation rules out that behavior by reusing the name field's type:
setName : part -> { whole | name : part } -> { whole | name : part }
setName newValue record =
{ record | name = newValue } Problem 3
type alias Lens whole part =
{ get : { whole | name : part } -> part
, set : part -> { whole | name : part } -> { whole | name : part }
}Problem 4
type alias Lens whole part =
{ get : whole -> part
, set : part -> whole -> whole
}
lens : (whole -> part) -> (part -> whole -> whole) -> Lens whole part
lens getter setter =
{ get = getter, set = setter }Problem 5
type alias Lens whole part =
{ get : whole -> part
, set : part -> whole -> whole
, update : (part -> part) -> whole -> whole
}
lens : (whole -> part) -> (part -> whole -> whole) -> Lens whole part
lens getter setter =
let
updater f whole =
setter (f (getter whole)) whole
in
{ get = getter, set = setter, update = updater }