haskell - Compiling a type class, Queue, with an instance for lists, don't work due to incomplete inference in GHC 7.8 -
trying compile next haskell program:
{-# language multiparamtypeclasses #-} {-# language flexibleinstances #-} import qualified data.list l class queue c e new :: c insert :: e -> c -> c extract :: c -> (e, c) empty :: c -> bool instance queue [e] e new = [] insert = (:) extract (x:xs) = (x,xs) empty = l.null tolist :: queue c e => c -> [e] tolist queue | empty queue = [] tolist queue = allow (first,rest) = extract queue in first : tolist rest main = print (new ([] :: [int]))
you next error:
[1 of 1] compiling main ( afff.hs, afff.o ) afff.hs:19:16: not deduce (queue c e1) arising utilize of ‘empty’ context (queue c e) bound type signature tolist :: queue c e => c -> [e] @ afff.hs:18:11-31 type variable ‘e1’ ambiguous relevant bindings include queue :: c (bound @ afff.hs:19:8) tolist :: c -> [e] (bound @ afff.hs:19:1) note: there potential instance available: instance queue [e] e -- defined @ afff.hs:12:10 in expression: empty queue in stmt of pattern guard equation ‘tolist’: empty queue in equation ‘tolist’: tolist queue | empty queue = [] afff.hs:22:8: no instance (show a0) arising utilize of ‘print’ type variable ‘a0’ ambiguous note: there several potential instances: instance show double -- defined in ‘ghc.float’ instance show float -- defined in ‘ghc.float’ instance (integral a, show a) => show (ghc.real.ratio a) -- defined in ‘ghc.real’ ...plus 24 others in expression: print (new ([] :: [int])) in equation ‘main’: main = print (new ([] :: [int])) afff.hs:22:15: no instance (queue ([int] -> a0) e0) arising utilize of ‘new’ in first argument of ‘print’, namely ‘(new ([] :: [int]))’ in expression: print (new ([] :: [int])) in equation ‘main’: main = print (new ([] :: [int])) shell returned 1
why ghc isn't able deduce "e1 = int", if case?
it's not case (e1 ~ int)
because (c ~ [int])
. in order utilize mptc, ghc needs know every type parameter it. type of empty
refers 1 of type parameters, never can used.
as aside, i'm pretty firmly of sentiment it's bug ghc not reject class definition immediately. it's impossible use, why wait until seek utilize reject it?
you might think because 1 instance matches c
type parameter you're ok, you're not. ghc doesn't care instances visible during class resolution. determines class needs exist, checks it.
in case, says "i know need c
be, but.. have no clue need e
be. can't tell instance i'm supposed use." in aside, problem obvious in definition of class itself.
the direct way solve functional dependency, this:
class queue c e | c -> e new :: c insert :: e -> c -> c extract :: c -> (e, c) empty :: c -> bool
that requires functionaldependencies
language extension use. specifies compiler type e
uniquely determined type c
. means rejects pair of instances have same type c
different types e
, , assumes if knows type c
has plenty info pick instance use.
haskell ghc type-inference typeclass
No comments:
Post a Comment