haskell - What am I doing wrong with this meant-to-be-trivial higher rank polymorphism exercise? -


over year ago, asked question how use proxy in haskell, , since have small amount of use of rankntypes ghc extension. trouble every time try work it, end bizarre error messages , hacking around code until go away. or else give up.

obviously don't understand higher rank polymorphism in haskell. try resolve that, decided right down simplest examples could, test assumptions , see if myself eureka moment.

first assumption - reason higher rank polymorphism isn't standard haskell 98 (or 2010?) feature that, provided accept not-that-obvious restrictions lot of programmers wouldn't notice, isn't needed. can define rank 1 , rank 2 polymorphic functions are, @ first sight, equivalent. if load them ghci , call them same parameters, they'll give same results.

so - simple example functions...

{-# language rankntypes #-}  rank0 :: [int] -> bool rank0 x = null x  rank1a :: [a] -> bool rank1a x = null x  rank1b :: forall a. [a] -> bool rank1b x = null x  rank2 :: (forall a. [a]) -> bool rank2 x = null x 

and ghci session...

ghci, version 7.4.2: http://www.haskell.org/ghc/  :? loading package ghc-prim ... linking ... done. loading package integer-gmp ... linking ... done. loading package base ... linking ... done. prelude> :load example01 [1 of 1] compiling main             ( example01.hs, interpreted ) ok, modules loaded: main. *main> 

no errors far - start. next, test each function empty list parameter...

*main> rank0 [] true *main> rank1a [] true *main> rank1b [] true *main> rank2 [] true *main> 

to honest, little surprised rank1a , rank1b functions worked in case. list doesn't know type elements contains, functions don't know either, yet surely type must decided make call? expecting need provide explicit signature somewhere.

that's not issue atm though, , results seem promising. next up, non-empty lists...

*main> rank0 [1,2,3] false *main> rank1a [1,2,3] false *main> rank1b [1,2,3] false *main> rank2 [1,2,3]  <interactive>:10:8:     no instance (num a)       arising literal `1'     in expression: 1     in first argument of `rank2', namely `[1, 2, 3]'     in expression: rank2 [1, 2, 3] *main> 

oh dear - seems rank 2 version doesn't when parameter knows bit more it's type. still, maybe issue literals 1 etc polymorphic...

*main> rank2 ([1,2,3] :: [int])  <interactive>:11:8:     couldn't match type `a' `int'       `a' rigid type variable bound           type expected context: [a] @ <interactive>:11:1     expected type: [a]       actual type: [int]     in first argument of `rank2', namely `([1, 2, 3] :: [int])'     in expression: rank2 ([1, 2, 3] :: [int]) *main> 

the error different, still didn't work , still don't understand these error messages.

messing around various theories, 1 idea had maybe need tell ghc "forget" of static type of list. on theory, tried various things including...

*main> [1,2,3] :: [a]  <interactive>:12:2:     no instance (num a1)       arising literal `1'     in expression: 1     in expression: [1, 2, 3] :: [a]     in equation `it': = [1, 2, 3] :: [a] *main> 

ok, ghci doesn't know i'm talking about. in case ghci needed know type forget, tried...

*main> ([1,2,3] :: [int]) :: [a]  <interactive>:15:2:     couldn't match type `a1' `int'       `a1' rigid type variable bound            expression type signature: [a1] @ <interactive>:15:1     expected type: [a]       actual type: [int]     in expression: ([1, 2, 3] :: [int]) :: [a]     in equation `it': = ([1, 2, 3] :: [int]) :: [a] *main> 

so hopes of getting error effect ghci doesn't know how show value forgotten type. don't know how construct list "forgotten" static type , i'm not sure makes sense.

at point i'm not trying useful higher rank polymorphism. point here able call rank2 function non-empty list, , understand why it's not working same other functions. want carry on figuring out step step myself, right i'm stuck.

let's think type of rank2 means.

rank2 :: (forall a. [a]) -> bool rank2 x = null x 

the first argument rank2 needs of type forall a. [a]. forall being outermost here means whoever gets such value can pick choice of a. think of taking type argument.

so, in order give argument rank2, needs list elements can of any type internal implementation of rank2 might want. since there's no way conjure values of such arbitrary type, possible inputs [] or lists containing undefined.

contrast rank1b:

rank1b :: forall a. [a] -> bool rank1b x = null x 

here forall outermost, whoever uses rank1b gets pick type.

a variation would work this:

rank2b :: (forall a. num => [a]) -> bool rank2b x = null x 

now can pass list of numeric literals, polymorphic on num instances. alternative this:

rank2c :: (forall a. [a -> a]) -> bool rank2c x = null x 

this works because can indeed conjure values of type forall a. -> a, function id.


Comments

Popular posts from this blog

Perl - how to grep a block of text from a file -

delphi - How to remove all the grips on a coolbar if I have several coolbands? -

javascript - Animating array of divs; only the final element is modified -