我有一个使用monoid实现的数据类型:
*.dll
newtype First' a =
First' {getFirst' :: Optional a}
deriving (Eq, Show)
instance Arbitrary a => Arbitrary (First' a) where
arbitrary = do
x <- arbitrary
frequency [ (1, return (First'(Only x)))
, (1, return (First' Nada))]
instance Monoid (First' a) where
mempty = First' Nada
mappend (First' (Only x)) _ = First' (Only x)
mappend (First' Nada) (First' (Only x)) = First' (Only x)
mappend _ _ = First' Nada
的最后一个实现说,如果它没有模式匹配前两个mappend
函数,那么第三个将被采用。
最后mappend
函数对我来说并不明显,我必须传递mappend
数据类型。对我来说,由于下划线,我可以传递任何数据类型。
当我使用函数时,haskell如何知道:
First'
最后一个是模式匹配的mappend (First' Nada) (First' Nada)
?
出于好奇,我试过了:
(mappend _ _)
但是haskell编译器抱怨。
*Main First Lib MonoidLaws> mappend 3 45
答案 0 :(得分:4)
您已宣布mappend
成为Monoid (First' a)
实例的一部分,因此mappend
的类型为
First' a -> First' a -> First' a
请注意,所有三个mappend
模式都缩进到实例声明的右侧。这意味着他们使用该类型确定到该实例的范围。
mappend _ _
是模式,但其类型是First' a -> First' a -> First' a
。通配符仅表示参数可以是任何First' a
值。