list - Haskell's head tail init and last in GHCi -
i have question head, tail, init , last. following works in ghci:
prelude data.list data.char> let n = [1..10] in (head n : tail n) [1,2,3,4,5,6,7,8,9,10] as expected, whole list. should work init , last too, right?
prelude data.list data.char> let n = [1..10] in (init n : last n) <interactive>:39:1: non type-variable argument in constraint: enum [[a]] (use flexiblecontexts permit this) when checking ‘it’ has inferred type :: forall a. (enum a, enum [[a]], num a, num [[a]]) => [[a]] if @ type signatures functions, head , last same -- both return element. init , tail same, because both return lists.
prelude data.list data.char> :info head head :: [a] -> -- defined in ‘ghc.list’ prelude data.list data.char> :info tail tail :: [a] -> [a] -- defined in ‘ghc.list’ prelude data.list data.char> :info init init :: [a] -> [a] -- defined in ‘ghc.list’ prelude data.list data.char> :info last last :: [a] -> -- defined in ‘ghc.list’ so non type-variable argument in constraint: enum [[a]] mean? if init n or last n without construction of new list, [1..9] , 10.
it true head/last , tail/init have identical types. if had swapped out last head , init tail, have had no problem:
> let n = [1..10] in last n : init n [10,1,2,3,4,5,6,7,8,9] but didn't. did both swap and another: changed order of arguments :. happens : doesn't take 2 arguments of same type:
> :t (:) (:) :: -> [a] -> [a] so last swap not okay! in fact, if give n more specific type signature, ghci give better error:
> let n :: [integer]; n = [1..10] in init n : last n <interactive>:1:50: couldn't match type ‘integer’ ‘[[integer]]’ expected type: [[[integer]]] actual type: [integer] in first argument of ‘last’, namely ‘n’ in second argument of ‘(:)’, namely ‘last n’ this error still not 100% clear, think bit of puzzling can see it's complaining about: since init n :: [integer], , (:) :: [integer] -> [[integer]] -> [[integer]], it's expecting last n :: [[integer]] , therefore n :: [[[integer]]]. explicitly said n :: [integer], conflict.
now, error gave in case? well, clue in type of [1..10]:
> :t [1..10] [1..10] :: (enum t, num t) => [t] notice [1..10] polymorphic. moreover, used twice in expression, , can given separate monomorphic types in 2 uses. [1..10] instantiated two different types in sequel!
now think can start see error got comes in. it's trying find type a which:
enum a-- needed..part ofinit [1..10]num a-- needed1,10parts ofinit [1..10]enum [[a]]-- ifinit n :: a, haveinit n : last nwell-typed, must havelast n :: [a], hence second occurrence ofnmust haven :: [[a]];enumconstraint needed..part oflast [1..10]num [[a]]-- similar reasoning, needed1,10parts oflast [1..10]
but these constraints hard satisfy -- there's no instance of enum , num lists in scope in prelude or data.list. complains.
Comments
Post a Comment