Folding recursive type family

I am trying to collapse data with a type like phantom [*]. Here is a simplified version of my code

{-# LANGUAGE DataKinds, KindSignatures #-}

module Stack where
import Data.HList
import Data.Foldable as F

data T (a :: [*]) = T (Tagged a String)
(!++!) :: T a -> T b -> T (HAppendList a b)
(T a) !++! (T b) = T (Tagged (untag a ++ untag b))


a = T (Tagged "1") :: T '[Int]
b = T (Tagged "-- ") :: T '[]
ab = a !++! b :: T '[Int]

I need a bend operator

(!++*) :: (Foldable t ) =>  T a -> t (T '[]) -> T a
a !++* t = F.foldl (!++!) a t

But that does not work. Compiler that aand HAppendList a '[]different, even though they are not.

Why can't compilation HAppendList a '[]and merge a?

(I can't do a manual bend in ghci, though :t a !++! b !++! b !++! b => T '[Int]

+4
source share
1 answer

Pay attention to the definition HAppendList:

type family HAppendList (l1 :: [k]) (l2 :: [k]) :: [k]
type instance HAppendList '[] l = l
type instance HAppendList (e ': l) l' = e ': HAppendList l l'

You and I know that []this is a left and right identity ++, but the compiler only knows about the left identifier:

happend' :: T a -> T b -> T (HAppendList a b)
happend' (T (Tagged a)) (T (Tagged b)) = (T (Tagged (a++b)))

-- Doesn't typecheck 
leftIdentity' :: T a -> T '[] -> T a 
leftIdentity' x y = happend' x y 

rightIdentity' :: T '[] -> T a -> T a 
rightIdentity' x y = happend' x y 

You will need

type instance HAppendList '[] l = l
type instance HAppendList l '[] = l
type instance HAppendList (e ': l) l' = e ': HAppendList l l'

; , . :

(!+++!) :: T a -> T b -> T (HAppendList a b) 
(!+++!) (T (Tagged x)) (T (Tagged y)) = T (Tagged (y ++ x))

(!++*) :: Foldable t => T a -> t (T '[]) -> T a
a !++* t = F.foldl (flip (!+++!)) a t

, ghc 7.8, :

type family (++) (a :: [k]) (b :: [k]) :: [k] where 
  '[] ++ x = x
  x ++ '[] = x
  (x ': xs) ++ ys = x ': (xs ++ ys)

happend :: T a -> T b -> T (a ++ b)
happend (T (Tagged a)) (T (Tagged b)) = (T (Tagged (a++b)))

leftIdentity :: T a -> T '[] -> T a 
leftIdentity x y = happend x y 

rightIdentity :: T '[] -> T a -> T a 
rightIdentity x y = happend x y 
+5

Source: https://habr.com/ru/post/1544819/


All Articles