简体   繁体   中英

Error trying to define custom bind operator in Haskell

So I have been researching a lot about monads lately and I am very new to the Haskell-programming language.

This is my code:

import Data.List
import System.IO

f :: Int -> (Int, [Char])
f x = (x, ['a'])

g :: Int -> (Int, [Char])
g y = (y, ['b'])

(>>=) :: (Int -> (Int, [Char])) -> (Int -> (Int, [Char])) -> Int -> (Int, [Char])
(>>=) f1 f2 a =  f1 (fst (f2 a))

h :: Int -> (Int, [Char])
h x = (>>=) g f x

The GHCI-Compiler displays: error:

Ambiguous occurrence `>>='
It could refer to either `Prelude.>>='

What am I doing wrong? Am I using monads in the correct way?

You are defining a binding for (>>=) which is already bound by the prelude (as pointed out in the comments above).

So, you need to disambiguate each reference to it.

Give your module a name

module M where

and then, instead of writing

h x = (>>=) g f x

use either

h x = (M.>>=) g f x

or

h x = (Prelude.>>=) g f x

to choose which version of >>= you want.

However , this is not what you actually want to do, I think. This (>>=) will be a binding which has nothing to do with the Monad class.

To answer this properly, we have to check that your assumed and actual knowledge match up with the definitions the Haskell community has for this knowledge.

So, to begin, you obviously understand what types are, and it seems like you understand polymorphic types reasonably well.

Because Monad is a typeclass, and typeclasses use polymorphic types and because typeclasses can also use algebraic data types , it's a good idea to make sure you have a firm understanding of those things before attempting to understand Monad . Typeclasses are very similar to interfaces in other langauges - they define an abstract set of mandatory and optional functions (and their types) that a particular typeclass instance must adhere to. Often they also give you "free" functionality with default definitions of other functions. They're very very cool :)

There are many good places where you can gain a good understanding of what typeclasses are. I'd point you to http://www.happylearnhaskelltutorial.com/1/output_other_things.html as a simple introduction (full disclosure, I helped write this), and the typeclassopedia, which will also explain about Monads a bit more, too (and give you the requisite knowledge) https://wiki.haskell.org/Typeclassopedia

I should mention, also, if you have the money and you want good lengthy exercises to really flesh out your understanding, check out http://haskellbook.com — it's fairly lengthy, but would probably be very useful for you, also generally to give you a good working understanding of the basics of Haskell.

It's very important to realise that there is a big difference between using a Monad instance, of which the prelude contains many common ones, and making a Monad instance, which is what it appears you're trying to do above.

Then, also, there's the definition of the Monad typeclass itself, often given as an example in books, and which can help you to understand how Monad instances work.

Eventually you'll need to look up the general definitions of the functions contained in the Monad typeclass anyway to fully understand how it's working, but it's good to keep an understanding that these three things are quite separate and yet often interchangeably described as "Monad" by people. (For example the value Just 5 could be described as a monadic value, but often people will just say it's a monad, even though that's technically incorrect in a subtle way... because Maybe has a Monad instance defined for it, and Just 5 is a Maybe value. You could also talk about the definition of the Monad instance for Maybe and look up how it's implemented, or even define it yourself, so long as you make sure you don't have it in scope when you try to defin it by doing one of the following: hide the default Maybe in the prelude, don't import the prelude, or name your version of Maybe something else, like MyMaybe .

So, I would recommend starting with understanding the difference between these three things. Armed with that knowledge, read the two references I gave you, and start with reading code that uses typeclasses, then read some code that uses Monad instances — for a few different types to give you an intuition, then move on to reimplementing a prelude Monad or two yourself, then finally trying to create your own version of the Monad typeclass without looking at the prelude one so you can test your own understanding of the functions. Then you'll have a really good understanding of them :)

Also worth noting that it's probably a good idea to tackle the path of typeclasses up to Monad before you get there. You'll probably have to do this anyway, but they are Functor , Applicative , and then finally Monad . You can optionally add Semigroup and Monoid in before Functor , but that's just to give you more typeclass understanding more than a necessity for understanding the Monad typeclass.

Good luck!

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