简体   繁体   中英

It could refer to either `Data.Monoid.<>'

I have following declaration:

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)

And tried it in the prelude:

*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)

How can I use mappend function from Semigroup for Two datatype in prelude?

Try it with something that's an instance of Semigroup, like List .

For example:

> (Two "1" "2") <> (Two "3" "4")

Two "13" "24"

In your attempt / example, a and b , c and d are not defined, so Haskell sees them as variables. Because you're using = between them, it's assuming you want to do pattern matching, so it's trying to match them to themselves, which is causing an infinite loop (as that is perfectly valid Haskell — to define values in terms of themselves). This is causing an error, though, because it would imply an infinite type , which it definitely seems is not what you want.

It might be worth starting with some simpler things, possibly. A good basic book which I helped author is http://happylearnhaskelltutorial.com but that doesn't deal with instantiating your own typeclasses. Having said that it'll give you a reasonably good understanding of pattern matching, variables, types and values which you'll need before you move on to understanding typeclasses enough to build your own instances.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM