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 of init [1..10]
  • num a -- needed 1 , 10 parts of init [1..10]
  • enum [[a]] -- if init n :: a, have init n : last n well-typed, must have last n :: [a] , hence second occurrence of n must have n :: [[a]]; enum constraint needed .. part of last [1..10]
  • num [[a]] -- similar reasoning, needed 1 , 10 parts of last [1..10]

but these constraints hard satisfy -- there's no instance of enum , num lists in scope in prelude or data.list. complains.


Comments

Popular posts from this blog

sql - invalid in the select list because it is not contained in either an aggregate function -

Angularjs unit testing - ng-disabled not working when adding text to textarea -

How to start daemon on android by adb -