我有以下声明:
data Two a b = Two a b deriving (Eq, Show)
instance (Semigroup a, Semigroup b) => Semigroup (Two a b) where
(Two a b) <> (Two c d) = Two (a <> c) (b <> d)
Run Code Online (Sandbox Code Playgroud)
并在前奏中尝试过:
*Main First Lib MonoidLaws Semi> (Two a b) <> (Two c d) = Two (a <> c) (b <> d)
<interactive>:10:3: error:
* Occurs check: cannot construct the infinite type: t1 ~ Two t1 t1
Expected type: t1 -> t -> b
Actual type: Two t1 t1 -> Two t t -> Two b b
* Relevant bindings include
(<>) :: t1 -> t -> b (bound at <interactive>:10:3)
Run Code Online (Sandbox Code Playgroud)
如何在前奏中使用mappend函数from Semigroupfor Twodatatype?
尝试使用Semigroup的实例,比如List.
例如:
> (Two "1" "2") <> (Two "3" "4")
Two "13" "24"
Run Code Online (Sandbox Code Playgroud)
在您的尝试/示例中,a并且b,c并且d未定义,因此Haskell将它们视为变量.因为你=在它们之间使用它,它假设你想要进行模式匹配,所以它试图将它们与自己匹配,这导致无限循环(因为这是完全有效的Haskell - 根据它们自己定义值).然而,这会导致错误,因为它意味着无限类型,它看起来绝对不是你想要的.
可能值得从一些更简单的事情开始.我帮助创作的一本好的基础书是http://happylearnhaskelltutorial.com,但这并不涉及实例化你自己的类型类.已经说过,它会让你对模式匹配,变量,类型和值有一个相当不错的理解,在你继续理解类型类足以构建自己的实例之前,你需要它们.