2017-02-06 117 views
1

我一直given下面的类接口:通用嵌套monad操作?

class Misty m where 
    banana :: (a -> m b) -> m a -> m b 
    unicorn :: a -> m a 

现在我需要修改这个来启用:

jellybean :: (Misty m) => m (m a) -> m a 

我相信这个问题是推动我补充的子类Misty,多参数:

class Misty m => VeryMisty m a where 
    ... banana' (Just (Just v)) = banana --? 

我不确定如何在Misty创建一个函数来在这个嵌套monad上运行?

我也不确定我的方法是否正确和/或最简单?

+1

我想你只需要用'banana'和'unicorn'来定义'jellybean' – Euge

+1

你确实知道'Misty'是'Monad','banana'是'= <<'(翻转的'' ='),'unicorn'是'return','jellybean'是'join',对吧? – chepner

回答

5

我想你不必扩展类,或者添加一个子类。考虑一下的banana类型签名看上去一样,如果你会选择m aabanana的签名(类型变量a可以代表任何类型的,所以也为m a):

banana :: Misty m => (m a -> m b) -> m (m a) -> m b 

你看到这已经开始看起来非常接近jellybean?您只需“摆脱”第一个参数,并使ba相同。实现这一目标最简单的方法是使用身份功能id

jellybean :: (Misty m) => m (m a) -> m a 
jellybean x = banana id x 

一个很好的办法看到第二个步骤更容易的是,一旦你发现,你可以使用的第一个参数jellybeanbanana第二是使用类型化孔

jellybean :: (Misty m) => m (m a) -> m a 
jellybean x = banana _ x 

在装载该进入REPL,哈斯克尔会打印出:

Found hole `_' with type: m a -> m a 

所以你看这里你需要什么来做这个类型检查。