Haskell 为新数据类型创建 map 和 foldr 函数
Haskell creating map and foldr function for new datatype
我写了一个数据结构,
data Bit a = Add a (Bit a) | End deriving (Show,Eq)
data Bits a = Bits (Bit a) (Bit a) deriving (Show,Eq)
但我正在努力为他们创建地图和文件夹功能。
到目前为止我有这个:
instance Functor Bit
where
fmap _ (End) = End
fmap f (Add x (y)) = Add (f x) $ (fmap f y)
instance Foldable Bit
where
foldr _ z (End) = z
foldr f z (Add x (y)) = f x $ foldr f z y
instance Functor Bits
where
fmap _ (Bits (End) (End)) = Bits (End) (End)
fmap f (Bits (Add x (y)) (End)) = error "dont know what to put here"
instance Foldable Bits
where
foldr _ z (Bits (End) (End)) = z
foldr f z (Bits (Add x (y)) (End) = Bits (f x $ f y) (End)
foldr f z (Bits (Add x (y)) (Add a (b)) = error "dont know"
知道如何实施它们吗?也不确定我是否遗漏了什么,所以请告诉我是否也是这种情况。
也许通过 foldMap
:
实现 Foldable
实例更容易
import Data.Monoid
data Bit a = Add a (Bit a) | End deriving (Show,Eq)
data Bits a = Bits (Bit a) (Bit a) deriving (Show,Eq)
instance Functor Bit where
fmap _ End = End
fmap f (Add x b) = Add (f x) $ fmap f b
instance Foldable Bit where
foldMap _ End = mempty
foldMap f (Add x b) = f x <> foldMap f b
instance Functor Bits where
fmap f (Bits l r) = Bits (fmap f l) (fmap f r)
instance Foldable Bits where
foldMap f (Bits l r) = foldMap f l <> foldMap f r
这里有一些 GHCi 示例:
*Q51009307> foldr (\x a -> show x ++ a) "" $ End
""
*Q51009307> foldr (\x a -> show x ++ a) "" $ Add 1 $ End
"1"
*Q51009307> foldr (\x a -> show x ++ a) "" $ Add 1 $ Add 2 $ End
"12"
*Q51009307> foldr (\x a -> show x ++ a) "" $ Add 1 $ Add 2 $ Add 3 $ End
"123"
*Q51009307> foldMap Sum $ Bits (Add 1 $ End) End
Sum {getSum = 1}
*Q51009307> foldMap Sum $ Bits (Add 1 $ Add 2 $ End) (Add 1 $ End)
Sum {getSum = 4}
*Q51009307> foldr (+) 0 $ Bits (Add 1 $ Add 2 $ End) (Add 1 $ End)
4
我写了一个数据结构,
data Bit a = Add a (Bit a) | End deriving (Show,Eq)
data Bits a = Bits (Bit a) (Bit a) deriving (Show,Eq)
但我正在努力为他们创建地图和文件夹功能。
到目前为止我有这个:
instance Functor Bit
where
fmap _ (End) = End
fmap f (Add x (y)) = Add (f x) $ (fmap f y)
instance Foldable Bit
where
foldr _ z (End) = z
foldr f z (Add x (y)) = f x $ foldr f z y
instance Functor Bits
where
fmap _ (Bits (End) (End)) = Bits (End) (End)
fmap f (Bits (Add x (y)) (End)) = error "dont know what to put here"
instance Foldable Bits
where
foldr _ z (Bits (End) (End)) = z
foldr f z (Bits (Add x (y)) (End) = Bits (f x $ f y) (End)
foldr f z (Bits (Add x (y)) (Add a (b)) = error "dont know"
知道如何实施它们吗?也不确定我是否遗漏了什么,所以请告诉我是否也是这种情况。
也许通过 foldMap
:
Foldable
实例更容易
import Data.Monoid
data Bit a = Add a (Bit a) | End deriving (Show,Eq)
data Bits a = Bits (Bit a) (Bit a) deriving (Show,Eq)
instance Functor Bit where
fmap _ End = End
fmap f (Add x b) = Add (f x) $ fmap f b
instance Foldable Bit where
foldMap _ End = mempty
foldMap f (Add x b) = f x <> foldMap f b
instance Functor Bits where
fmap f (Bits l r) = Bits (fmap f l) (fmap f r)
instance Foldable Bits where
foldMap f (Bits l r) = foldMap f l <> foldMap f r
这里有一些 GHCi 示例:
*Q51009307> foldr (\x a -> show x ++ a) "" $ End
""
*Q51009307> foldr (\x a -> show x ++ a) "" $ Add 1 $ End
"1"
*Q51009307> foldr (\x a -> show x ++ a) "" $ Add 1 $ Add 2 $ End
"12"
*Q51009307> foldr (\x a -> show x ++ a) "" $ Add 1 $ Add 2 $ Add 3 $ End
"123"
*Q51009307> foldMap Sum $ Bits (Add 1 $ End) End
Sum {getSum = 1}
*Q51009307> foldMap Sum $ Bits (Add 1 $ Add 2 $ End) (Add 1 $ End)
Sum {getSum = 4}
*Q51009307> foldr (+) 0 $ Bits (Add 1 $ Add 2 $ End) (Add 1 $ End)
4