It's a niggle, but I think it's more correct to say that type inference 
isn't completely decidable in the presence of subtyping.

On Friday, October 6, 2017 at 6:45:42 AM UTC-7, Rémi Lefèvre wrote:
>
> Thank you very much, this is perfectly clear.
>
> For some reason, I was confused by extensible records and thought I could 
> express a type of functions that are guaranteed to not use any record field 
> not defined by the Named type alias.
> Of course this is wrong and consistent with the rest of the language. 
> Actually my contrived example is as absurd as the simpler:
>
> fails : (a -> b) -> b
> fails func =
>     func ()
>
> life =
>     fails (\_ -> 42)
>
> I think that what I confusingly expected of extensible records in this 
> case was more like a typeclass implementing the `.name : a -> Maybe String` 
> operation.
> And that's why extensible records are AFAIK only mainly used to narrow 
> functions arguments currently.
>
>
> So thank you again for having cleared my mind.
>
>
> On Wednesday, October 4, 2017 at 11:13:34 PM UTC+2, Ilias Van Peer wrote:
>>
>> 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