Haskell type annotation in function -
haskell doesn't seem recognize type annotation below. why this?
here runner wrapper function, default starting value c (a "continuant"). in rmap, want c have default "starting" value (for example, if c [a] let value []). what's of course inconvenient here (and perhaps bad practice, feel free suggest better way) type annotation required since domain of rmap not involve type c. however, why can not fix type annotation?
data exitcode = fail | ok | success deriving (eq, show) data runner b c = runner {cont ::c , fun :: (a, c , exitcode) ->(b, c, exitcode)} class pointed point :: rmap:: (pointed c) => (a->b) -> runner b c rmap f = runner (point::c) (\(x,y,z) -> (f x,y,z))
the error following. (it seems interpreting c c1.)
could not deduce (pointed c1) arising use of `point' context (pointed c) bound type signature rmap :: pointed c => (a -> b) -> runner b c @ runner.hs:39:8-44 possible fix: add (pointed c1) context of expression type signature: c1 or type signature rmap :: pointed c => (a -> b) -> runner b c in first argument of `runner', namely `(point :: c)' in expression: runner (point :: c) (\ (x, y, z) -> (f x, y, z)) in equation `rmap': rmap f = runner (point :: c) (\ (x, y, z) -> (f x, y, z))
in order use type variables in definition that, need scopedtypevariables
language extension, in case don't need scoped type variable @ all, use
rmap :: pointed c => (a -> b) -> runner b c rmap f = runner point (\(x, y, z) -> (f x, y, z))
if really want have (point :: c)
, can do
{-# language scopedtypevariables #-} -- other declarations rmap :: forall b c. pointed c => (a -> b) -> runner b c rmap f = runner (point :: c) (\(x, y, z) -> (f x, y, z))
with scopedtypevariables
have explicitly use forall
syntax , have a
, b
declared well. again, isn't necessary particular problem, ghc can automatically figure out instance of pointed
use.
even ghc 7.8, type signature isn't required, can derive automatically:
> let rmap f = runner point (\(x, y, z) -> (f x, y, z)) > :t rmap rmap :: pointed c => (a -> b) -> runner b c
the origin of error when had (point :: c)
without scopedtypevariables
, c
in function definition different c
in type signature. works concrete types int
because they're in scope, not type variables.
so why works without having c
in domain of function: ghc's type inference smart. it'll let pass around generic value until point require concrete, right instances used. example, if instead had like
> data test b c = test { t :: c, x :: (a, b) } deriving (eq, show) > instance pointed [double] point = [1, 2, 3] -- requires flexibleinstances > let test :: pointed c => -> b -> test b c | test b = test point (a, b) > test 1 "test" :: test int string [double] test {t = [1.0,2.0,3.0], x = (1,"test")}
even though c
doesn't appear argument, it's still possible type checker figure out instance use when i've specified return type test int string [double]
. without specifying signature, instead gives me error
<interactive>:30:1: no instance (pointed c0) arising use of `it' type variable `c0' ambiguous note: there potential instance available: instance pointed [double] -- defined @ <interactive>:19:10 in first argument of `print', namely `it' in stmt of interactive ghci command: print
because doesn't know instance of pointed
use.
Comments
Post a Comment