On Friday, February 10, 2017 at 3:26:38 PM UTC, Joey Eremondi wrote: > > So, Elm lets you do a forall over the rest of a record. > > {a | x : Int} -> Int says this function accepts any record that has an x > Int field. >
I am trying to build a model with states, such that fields are only available that are actually needed in the relevant state. The model is like this: type alias WithPosition a = { a | rect : Rectangle } type alias WithValue a = { a | value : String } type State = Hidden | Aware (WithPosition {}) | Active (WithPosition (WithValue {})) | Inactive (WithPosition (WithValue {})) It can be convenient to have functions to work on fields in the model, only when the state is such that those fields are available. Here is one such function: mapWhenWithPosition : (WithPosition {} -> a) -> State -> Maybe a mapWhenWithPosition func state = case state of Aware { rect } -> Just <| func { rect = rect } Active { rect } -> Just <| func { rect = rect } Inactive { rect } -> Just <| func { rect = rect } _ -> Nothing So when in a state that is 'positioned' this function lets me apply a function to the position and return the result in a Just, otherwise Nothing. Makes it easy to have a UI component that will only appear in certain states, for example. What I don't understand is why this fails to type check: mapWhenWithPosition : (WithPosition b -> a) -> State -> Maybe a mapWhenWithPosition func state = case state of Aware rect -> 105: Just <| func rect Active rect -> Just <| func rect Inactive rect -> Just <| func rect _ -> Nothing Complains that: The argument to function `func` is causing a mismatch. 105| func rect ^^^^ Function `func` is expecting the argument to be: WithPosition b But it is: WithPosition {} I marked in which line is 105 above. The function WithPosition b -> a is general enough to handle a WithPosition {}, but I seem to be only able to use it where it fully matches. This would seem to make extensible records a lot less useful than they could be. Is this one of those cases where an existential qualifier would be needed to specify the type of the function? Or is this in fact a case that could be typed in Elm without problem and that the type checker should accept? Or perhaps there is some other way of writing what I want? Inactive { rect } -> Just <| func { rect = rect } Isn't too bad, but it gets a lot worse when there are lots more fields and you are having to deconstruct then reconstruct the same record: SomeStatate { field1, field2, ..., fieldn } -> Just <| func { field1 = field1, field2 = field2, ..., fieldn = fieldn } -- You received this message because you are subscribed to the Google Groups "Elm Discuss" group. To unsubscribe from this group and stop receiving emails from it, send an email to elm-discuss+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/d/optout.