由于newtype在类型系统中被视为完全不同的类型,我想知道是否有任何方法可以使用模式匹配或使用newtype迭代列表,如下所示。
newtype
newtype Foo = Foo [Int] bar :: Foo -> Int bar (x : xs) = x + bar xs bar [] = 0
9w11ddsr1#
有多种选择。1.只需在适当的位置手动 Package /展开新类型。
bar (Foo (x : xs)) = x + bar (Foo xs) bar (Foo []) = 0
1.在列表上实现函数,并在传递给函数之前将其解包一次。
bar (Foo xs) = sum xs
1.创建一个接口,允许操作Foo值,就像它们是列表一样。
Foo
{-# LANGUAGE PatternSynonyms #-} {-# COMPLETE (:%), FooNil #-} pattern (:%) :: Int -> Foo -> Foo pattern x :% xs <- Foo (x : (Foo -> xs)) where x :% xs = Foo (x : getFoo xs) pattern FooNil :: Foo pattern FooNil = Foo [] bar :: Foo -> Int bar (x :% xs) = x + bar xs bar FooNil = 0
1.抽象。你并不真的需要特定的列表解构器,你只需要一些方法来实现对所包含数据的 fold。在base中有一个标准的Foldable类,但它要求你的容器对所包含的类型是参数化的。由于它不是参数化的,你需要使用mono-traversable包中的MonoFoldable类来代替。
base
Foldable
mono-traversable
MonoFoldable
import Data.MonoTraversable type instance Element Foo = Int import MonoFoldable Foo where ofoldr f (Foo (x:xs)) e = f x $ ofoldr f (Foo xs) e ofoldr _ (Foo []) e = e bar = ofoldr (+) 0
请注意,一般来说,这种函数应该使用 * 严格左折叠 * 而不是右折叠来实现。
1条答案
按热度按时间9w11ddsr1#
有多种选择。
1.只需在适当的位置手动 Package /展开新类型。
1.在列表上实现函数,并在传递给函数之前将其解包一次。
1.创建一个接口,允许操作
Foo
值,就像它们是列表一样。1.抽象。你并不真的需要特定的列表解构器,你只需要一些方法来实现对所包含数据的 fold。在
base
中有一个标准的Foldable
类,但它要求你的容器对所包含的类型是参数化的。由于它不是参数化的,你需要使用mono-traversable
包中的MonoFoldable
类来代替。请注意,一般来说,这种函数应该使用 * 严格左折叠 * 而不是右折叠来实现。