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 elm-discuss+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Reply via email to