[Haskell-cafe] Rank N Kinds
Wvv
vitea3v at rambler.ru
Thu Aug 1 22:32:08 CEST 2013
I still asking for good examples of ranNkinds data (and classes)
But now let's look at my example, TupleList
data TupleList (t :: **) = TupleNil | TupleUnit t (TupleList t)
we can easily define tupleList
tupleL :: TupleList ( (Int :: **) -> (String :: **) -> (Bool :: **) )
tupleL = TupleUnit 5 (TupleUnit "inside tuple" (TupleUnit True TupleNil)))
And we can easily define rankNkinds functions, which can only work with
rankNkinds data,
like fstL, sndL, headL, tailL (see my previous letter)
But Haskell is weak to work with truly rankNkinds functions.
Let's look at Functor
instance Functor (TupleList (a :: **)) where
fmap :: ?????
fmap = tmap
What's the signature of fmap? Even with rankNkinds we can't define a
signature. Without new extensions.
Let's look at tmap ~ map for list.
It's bit simplier for us
tmap :: ????
tmap _ TupleNil = TupleNil
tmap f (TupleUnit x xs) = TupleUnit (f x) (tmap f xs)
If we wish to work with `f` like in this example, we must use
`rankNkindsFunctions` extension.
It's very hard to implement this extension into Haskell (imho)
Let's think we've already had this extension and we have a `tmap`
Let's try to write rankNkinds functions for next tupleLists:
tupleL :: TupleList ( (Int :: **) -> (String :: **) -> (Bool :: **) )
tupleL = TupleUnit 5 (TupleUnit "inside tuple" (TupleUnit True TupleNil)))
tupleL' :: TupleList ( (Int :: **) -> (Int :: **) -> (Bool :: **) )
tupleL' = TupleUnit 5 (TupleUnit 42 (TupleUnit True TupleNil)))
tupleL'' :: TupleList ( (Int :: **) -> (Int :: **) -> (Int :: **) )
tupleL'' = TupleUnit 5 (TupleUnit 42 (TupleUnit 777 TupleNil)))
here they are:
f :: ((Int -> Int) :: **) -> ((String -> String) :: **) -> ((Bool -> Bool)
:: **)
f :: Int -> Int
f = (+ 2)
f :: String -> String
f = ("Hello " ++)
f :: Bool -> Bool
f = (True &&)
2nd:
f' :: c@((Int -> Int) :: **) -> c'@((Int -> Int) :: **) -> ((Bool -> Bool)
:: **)
f' :: c@(Int -> Int)
f' = (+ 2)
f' :: c'@(Int -> Int)
f' = (* 5)
f' :: Bool -> Bool
f' = (True &&)
3rd:
f'' :: c@((Int -> Int) :: **) -> c@((Int -> Int) :: **) -> c@((Int -> Int)
:: **)
f'' :: c@(Int -> Int)
f'' = (+ 2)
These functions not only look weird, they look like overloading, but they
are not.
But truly, they are really weird.
Le's look deeply at line `tmap f (TupleUnit x xs) = TupleUnit (f x) (tmap f
xs)`
Truly rankNkinds functions works like ST Monad and partly applied function
together!
This is awesome!
((Int -> Int) :: **) -> ((String -> String) :: **) -> ((Bool -> Bool) ::
**) `op` (Int ::*) =
(Int :: **) -> ((String -> String) :: **) -> ((Bool -> Bool) :: **)
>>> (Int :: **) -> ((String -> String) :: **) -> ((Bool -> Bool) :: **)
>>> `op` (String ::*) =
(Int :: **) -> (String :: **) -> ((Bool -> Bool) :: **)
>>> (Int :: **) -> (String :: **) -> ((Bool -> Bool) :: **) `op` (Bool ::*)
>>> =
(Int :: **) -> (String :: **) -> (Bool :: **)
<<==>> TupleUnit (f x) (TupleUnit (f x') (TupleUnit (f x'') TupleNil))
Ok. Now we are ready to redefine f'' in a general way.
We need to have one extra extension: RecursiveSignatures.
We add 2 quantifications: 'forany' and 'forrec' (it's just my suggestion,
may be is too complicated and exists easier way to do this):
f''' :: forany i. forrec{i} c. c@((Int -> Int) :: **) -> { -> c }
f''' :: forrec{i=0..3} c. c@(Int -> Int)
f''' = (+ 2)
Let's write `f` function using these quantifications:
g :: forany i. forrec{i} a c. c@(a -> a :: **) { -> c }
g :: forrec c{0}. Int -> Int <<==>> g :: forrec c{0} (a{0} ~ Int). a ->
a
g = (+ 2)
g :: forrec c{1}. String -> String
g = ("Hello " ++)
g :: forrec c{2}. Bool -> Bool
g = (True &&)
And now it is possible to write signatures to `tmap` and `fmap`
tmap :: forany i. forrec{i} a b c c' c''. c@( (a -> b) :: **) { -> c } ->
c'@(a :: * :: **) { -> c' } -> c''@(b :: * :: **) { -> c'' }
fmap :: forany i. forrec{i} a b c c' c''. c@( (a -> b) :: **) { -> c } -> f
(c'@(a :: **) { -> c' }) -> f (c''@(b :: **) { -> c'' })
P.S. We could write foldr function for our tupleLists as:
folded :: Bool
folded = foldr h True tupleL
h :: forany i. forrec{i} a c. c@( a -> b -> b :: **) { -> c }
h :: forrec c{0}. Int -> Bool -> Bool
h :: forrec c{1}. String -> Bool -> Bool
h :: forrec c{2}. Bool -> Bool -> Bool
P.S.S. All this staff is open for discussion ))
cheers, Wvv
--
View this message in context: http://haskell.1045720.n5.nabble.com/Rank-N-Kinds-tp5733482p5733699.html
Sent from the Haskell - Haskell-Cafe mailing list archive at Nabble.com.
More information about the Haskell-Cafe
mailing list