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.