Whole Story Recursion Does Not Work in Elm 0.19
module SumTypes.WholeStorySolution exposing (..)
type Silly a b
= AsA a
| AsB b
| AlsoAsA a
| AsInt Int
| AsFloatString Float String
| AsBoth a b
| AsIntB Int b
| AsMaybe (Maybe b)
| AsMaybeInt (Maybe Int)
| DeeplySilly (Silly a a) (Silly Int b)
| NoArg
bVals : Silly a b -> Maybe b
bVals silly =
case silly of
AsB b -> Just b
AsBoth _ b -> Just b
AsIntB _ b -> Just b
AsMaybe (Just b) -> Just b -- could just be AsMaybe maybe -> maybe
DeeplySilly _ nested -> bVals nested -- <--- Problem here
_ -> Nothing
Produces an error on 0.19:
Detected errors in 1 module.
-- TYPE MISMATCH --------------------------------------------- src/SumTypes/WholeStorySolution.elm
The 1st argument to `bVals` is not what I expect:
171| bVals nested
^^^^^^^^^^
This `nested` value is a:
Silly Int b
But `bVals` needs the 1st argument to be:
Silly a b
Hint: Your type annotation uses type variable `a` which means ANY type of value
can flow through, but your code is saying it specifically wants a `Int` value.
Maybe change your type annotation to be more specific? Maybe change the code to
be more general?
Hmm. I'm confused by why it's wrong. Probably missing something obvious. I'll have to try it on PureScript and see if it's also an error there.
I expect there are a lot of 0.19 problems, but I'm going to be slow to fix them. (First I'm looking into just having people install 0.18 instead if I can figure out how.)
It feels like a corner case or possibly even a bug (the function name being bound to the type it was applied to within the function?), but being this new to the language I’m assuming I’m just missing something about the way type variables work. I have seen the "too general" type error before, after all.
This is additionally interesting:
> bVals
<function> : Silly Int a -> Maybe a -- The inferred type
> AsStringFloat "hi" 4.5 |> bVals
Nothing : Maybe b -- …Why is this not an error, it doesn’t conform to the type?
I posted on the Elm slack, too, see if anybody chimes in with an explanation :)
Did you get anything from the Elm slack? I didn't see anything.
I ported the code to PureScript, and it compiles fine:
module Main where
import Prelude
import Data.Maybe (Maybe(..), isNothing)
data Silly a b
= AsA a
| AsB b
| AlsoAsA a
| AsInt Int
| AsFloatString Number String
| AsBoth a b
| AsIntB Int b
| AsMaybe (Maybe b)
| AsMaybeInt (Maybe Int)
| DeeplySilly (Silly a a) (Silly Int b)
| NoArg
simplify :: forall a b . Silly a b -> Silly a b
simplify silly =
case silly of
AsA _ -> silly
AsB _ -> silly
_ -> NoArg
bVals1 :: forall a b. Silly a b -> Maybe b
bVals1 silly =
case silly of
AsB b -> Just b
_ -> Nothing
bVals :: forall a b. Silly a b -> Maybe b
bVals silly =
case silly of
AsB b -> Just b
AsBoth _ b -> Just b
AsIntB _ b -> Just b
AsMaybe (Just b) -> Just b -- could just be AsMaybe maybe -> maybe
DeeplySilly _ nested -> bVals nested
_ -> Nothing
So I'm inclined to call this a bug in Elm. Will file it unless you want to.
No answer as yet—I’ll give it another day and file if nobody has an answer :)
Send me a link when you do, or @marick me. I'll be interested.