Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Infinite type error on type that does not appear to be infinite #1614

Open
evancz opened this issue Jul 14, 2017 · 4 comments
Open

Infinite type error on type that does not appear to be infinite #1614

evancz opened this issue Jul 14, 2017 · 4 comments
Labels

Comments

@evancz
Copy link
Member

evancz commented Jul 14, 2017

Summary and update of @mkolosick's report in #956.

The following code:

import Array exposing (Array)

type alias Focus big small =
    { get : big -> small
    , update : (small -> small) -> big -> big
    }

arrayFocus : Int -> Focus (Array a) a
arrayFocus index =
  Focus (Array.get index) (arrayUpdate index)

arrayUpdate index f array =
  case Array.get index array of
    Just val -> Array.set index (f val) array

Results in the following error with the pre-0.19 compiler:

-- INFINITE TYPE -----------------------------------------------------

I am inferring a weird self-referential type for `arrayFocus`:

139| arrayFocus : Int -> Focus (Array a) a
140| arrayFocus index =
141|   Focus (Array.get index) (arrayUpdate index)
       ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Here is my best effort at writing down the type. You will see ∞ for parts of the
type that repeat something already printed out infinitely.

    Focus (Array a) a

Usually staring at the type is not so helpful in these cases, so definitely read
the debugging hints for ideas on how to figure this out:
<https://github.com/elm-lang/elm-compiler/blob/0.19.0/hints/infinite-type.md>

What is going on here? Is this error message legitimate? If so, why does it read so badly? If not, what is going on to cause this?

@process-bot
Copy link

Thanks for the issue! Make sure it satisfies this checklist. My human colleagues will appreciate it!

Here is what to expect next, and if anyone wants to comment, keep these things in mind.

@allanderek
Copy link

allanderek commented Aug 4, 2017

Hi,

I think the error message is legitimate in the sense that it should fail to compile. The problem is that Array.get returns a Maybe a, but in the definition of arrayFocus it is being used as if its type was Array a -> a. To get the example to compile you can change the type alias to be:

type alias Focus big small =
    { get : big -> Maybe small
    , update : (small -> small) -> big -> big
    }

So in particular get: big -> Maybe small.

So I think the issue here is the first of your options, "why does it read so badly".

@allanderek
Copy link

Just to add that I think the following is a more minimal example:

type alias Bad small big =
    { f : big -> small
    , g : big -> small
    }

toMaybe : a -> Maybe a
toMaybe a = Just a

identity : a -> a
identity a = a

bad = Bad toMaybe identity

Which gives the error:

I am inferring a weird
self-referential type for `bad`:

16| bad = Bad toMaybe identity
    ^^^
Here is my best effort at
writing down the type. You will
see ∞ for parts of the type that
repeat something already printed
out infinitely.

    Bad (Maybe ∞) (Maybe ∞)

Usually staring at the type is
not so helpful in these cases,
so definitely read the debugging
hints for ideas on how to figure
this out:
<https://github.com/elm-lang/elm-compiler/blob/0.19.0/hints/infinite-type.md>

@allanderek
Copy link

In fact you don't actually need the second type variable:

type alias Bad a =
    { f : a -> a
    , g : a -> a
    }

toMaybe : a -> Maybe a
toMaybe a = Just a

identity : a -> a
identity a = a

bad = Bad toMaybe identity

Which gives:

I am inferring a weird
self-referential type for `bad`:

16| bad = Bad toMaybe identity
    ^^^
Here is my best effort at
writing down the type. You will
see ∞ for parts of the type that
repeat something already printed
out infinitely.

    Bad (Maybe ∞)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

3 participants