mapNamed : (Named a -> b) -> Element -> b

In that line, you say that I can pass in a function that works on `Named a`, 
where `a` isn't bound to anything. So if I were to write a function `foo : 
Named { iAlsoNeedAnInt : Int } -> Int`, I could pass that to that `mapNamed`. 
However `Element` contains a very *specific* type of `Named a` - it is a `Named 
{}`.

So one thing you could do is changing the annotation to say `mapNamed : 
(Named {} -> b) -> Element -> b`. Note that this would fall apart as soon 
as the different values in `Element` actually have different types.

Note that this isn't unique to extensible records, or even records at all. 
Say you wanted to allow passing `identity` in. You could try `mapNamed : (a 
-> b) -> Element -> Element`, but that also wouldn't work.. Because I could 
pass in `(\x -> x * 7)` which has type `number -> number`, which is valid 
according to the `a -> a` shape.

I hope this clarifies things a little?

Op woensdag 4 oktober 2017 16:19:45 UTC+2 schreef Rémi Lefèvre:
>
> Hi,
>
> Does anyone know if there is a way to use higher-order functions with a 
> function using an extensible record?
>
> When I try to build this code:
>
> type alias Named a =
>    { a | name : Maybe String }
>
> getName : Named a -> Maybe String
> getName { name } =
>    name
>
> type Element
>    = AnElement { name : Maybe String }
>    | AnotherElement { name : Maybe String }
>
> mapNamed : (Named a -> b) -> Element -> b
> mapNamed func element =
>    case element of
>      AnElement e ->
>         func e
>
>      AnotherElement e ->
>         func e
>
> getElementName : Element -> Maybe String
> getElementName e =
>    mapNamed getName e
>
>
>
> I get the following error:
>
> Detected errors in 1 module. -- TYPE MISMATCH 
> ----------------------------------- Types.elm The argument to function 
> `func` is causing a mismatch. 13| func e ^ Function `func` is expecting 
> the argument to be: Named a But it is: { name : Maybe String } Hint: Your 
> type annotation uses type variable `a` which means any type of value can 
> flow through. Your code is saying it CANNOT be anything though! Maybe 
> change your type annotation to be more specific? Maybe the code has a 
> problem? More at: <
> https://github.com/elm-lang/elm-compiler/blob/0.18.0/hints/type-annotations.md>
>  
>
>
>
> I struggle to understand why this does not work whereas replacing *func* 
> by *getName* satisfies the compiler:
>
> getElementName : Element -> Maybe String
> getElementName element =
>   case element of
>   AnElement e ->
>   getName e
>
>   AnotherElement e ->
>   getName e
>
>
> Any idea ?
>
> Thank you and sorry if this has been already discussed, I did not find 
> anything.
>
>
>
>

-- 
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 [email protected].
For more options, visit https://groups.google.com/d/optout.

Reply via email to