使用bind在haskell中调用自定义monad

Pis*_*tor 2 console monads haskell functional-programming ghci

我目前正在“接触单子”(http://learnyouahaskell.com/a-fistful-of-monads#getting-our-feet-wet-with-maybe),并且仍在为这个概念的一部分而苦苦挣扎。我理解那里提到的 Maybe monad,并且可以看到如何调用它,如下所述:

ghci> return "WHAT" :: Maybe String  
Just "WHAT"  
ghci> Just 9 >>= \x -> return (x*10)  
Just 90  
ghci> Nothing >>= \x -> return (x*10)  
Nothing  
Run Code Online (Sandbox Code Playgroud)

然而,如果我用自己的类型声明我自己的实例,我该如何调用我自己的 monad 实例而不是可能的实例,如下所示:

newtype CustomM a = CustomM {runCustomM:: a -> String}


instance Monad CustomM where
  return a = CustomM (\a -> mempty)
  m >>= f = CustomM (\a -> mempty)


instance Functor CustomM where 
  fmap = liftM 
instance Applicative CustomM where 
  pure = return; (<*>) = ap

Run Code Online (Sandbox Code Playgroud)

使用returnwill 只是调用Maybe Monad我怀疑。那>>=它需要我给它某种类型呢?

注意。我只以与返回相同的方式进行绑定,因为我仍然很难理解它应该返回什么,以及当我没有指定时,如何给它一个 monadm并在它的 value 上调用函数 fa左侧的包装类型更彻底。但我将就此发表另一篇文章。

Mar*_*ann 6

CustomM您可以像使用 一样创建您的类型的值Maybe,使用return

cm = return "WHAT" :: CustomM String
Run Code Online (Sandbox Code Playgroud)

您也可以运行它,以某种方式:

Prelude Control.Monad> runCustomM cm "foo"
""
Run Code Online (Sandbox Code Playgroud)

但显然,由于您已将其硬编码为 return mempty,因此它返回mempty的值String,即""

不过,所有这些在 中a -> String都是逆变的a,因此它不可能是一个有用的Functor实例。既然它不可能是一个有用的Functor实例,那么它也不可能是一个有用的Monad实例。

CustomM虽然您可以像在 OP 中一样定义退化实现,但您在真正做任何事情时不会取得太大成功。

相反,尝试交换类型,例如String -> a