Haskell 部分应用MPLU以无点方式重写函数

Haskell 部分应用MPLU以无点方式重写函数,haskell,applicative,Haskell,Applicative,我正在学习一些Haskell教程,试图熟悉这门语言。我在Monad/MonadPlus教程中看到了这个示例: data Sheep = Sheep {name :: String, mother :: Maybe Sheep, father :: Maybe Sheep} parent :: Sheep -> Maybe Sheep parent s = mother s `mplus` father s 作为练习,我试图用无点风格重写它,并不是说上面的内容是错误的或不惯用的,但我陷入了

我正在学习一些Haskell教程,试图熟悉这门语言。我在Monad/MonadPlus教程中看到了这个示例:

data Sheep = Sheep {name :: String, mother :: Maybe Sheep, father :: Maybe Sheep}
parent :: Sheep -> Maybe Sheep
parent s = mother s `mplus` father s
作为练习,我试图用无点风格重写它,并不是说上面的内容是错误的或不惯用的,但我陷入了困境:显然我可以编写自定义函数

partialPlus :: (MonadPlus m) => (a -> m b) -> (a -> m b) -> a -> m b
partialPlus f1 f2 = \x -> f1 x `mplus` f2 x
然后使用

parent = partialPlus mother father
但我似乎还记得,在LYAH教程中,有一种方法可以使用函子或应用函子来构造计算树,最终可以向其提供参数,从而从函子框中得到结果。然而,我似乎在教程中找不到这个例子。如何巧妙地重写上述内容?

非常简单 你可以把它写成

partialPlus :: MonadPlus m => (t -> m a) -> (t -> m a) -> t -> m a
partialPlus = liftM2 mplus
这是因为->t的monad实例可以理解为t->

更详细的类型:

liftM2 :: Monad func_t => (a -> b -> c) -> func_t a -> func_t b -> func_t c
给它一个非常有偏见的名字func_t建议函数从t到

那么

liftM2 mplus :: (Monad func_t, MonadPlus m) => func_t (m a) -> func_t (m a) -> func_t (m a)
但是既然你能有更好的应用程序,为什么还要使用Monad呢? 或者为什么我偷了hammar的好答案:

现在,有一个->t的应用程序实例,因此我们可以编写

partialPlus = liftA2 mplus
同样的道理。但这是个好消息,因为若你们能使用liftA2或liftA3等工具,你们就可以用很棒的控件来实现

一般来说,如果你有

this = do
  x <- mx
  y <- my
  z <- mz
  return (f x y z)
哪一个是免费的。。。只要你认为T-> A不是一个点! 非常免费 你可以把它写成

partialPlus :: MonadPlus m => (t -> m a) -> (t -> m a) -> t -> m a
partialPlus = liftM2 mplus
这是因为->t的monad实例可以理解为t->

更详细的类型:

liftM2 :: Monad func_t => (a -> b -> c) -> func_t a -> func_t b -> func_t c
给它一个非常有偏见的名字func_t建议函数从t到

那么

liftM2 mplus :: (Monad func_t, MonadPlus m) => func_t (m a) -> func_t (m a) -> func_t (m a)
但是既然你能有更好的应用程序,为什么还要使用Monad呢? 或者为什么我偷了hammar的好答案:

现在,有一个->t的应用程序实例,因此我们可以编写

partialPlus = liftA2 mplus
同样的道理。但这是个好消息,因为若你们能使用liftA2或liftA3等工具,你们就可以用很棒的控件来实现

一般来说,如果你有

this = do
  x <- mx
  y <- my
  z <- mz
  return (f x y z)

哪一个是免费的。。。只要你认为T-> A不是一个点! 将应用程序实例用于函数:

parent :: Sheep -> Maybe Sheep
parent = mplus <$> mother <*> father

将应用程序实例用于函数:

parent :: Sheep -> Maybe Sheep
parent = mplus <$> mother <*> father

见鬼,我发誓这就是我想到的并首先尝试的:我不知道为什么它不起作用。谢谢奖励:如何编写祖父母::绵羊->可能是无点风格的绵羊?它应该是类似mplus父级的东西???母亲和父母???爸爸,在哪里???再次是应用性的或一元的,因此您不能正确地传播任何内容。似乎我总是在想变得聪明的时候陷入困境…@BruceBerry:你可以使用>=>aka。Kleisli复合运算符,类似于翻转。有了单子,祖父母=父母>=>父母。谢谢。似乎大多数monad教程都没有介绍这个操作符,尽管我已经看过很多次了。再说一次,我可能太聪明了,不利于我自己,而祖父母s=父亲s>>>=父母`mplus`母亲>>=父母很好,但haskell图书馆的作者似乎并不真正接受简单,所以在理解他们的代码之前,我还有一些工作要做:-见鬼,我发誓这就是我想到并首先尝试的:我不知道为什么它不起作用。谢谢奖励:如何编写祖父母::绵羊->可能是无点风格的绵羊?它应该是类似mplus父级的东西???母亲和父母???爸爸,在哪里???再次是应用性的或一元的,因此您不能正确地传播任何内容。似乎我总是在想变得聪明的时候陷入困境…@BruceBerry:你可以使用>=>aka。Kleisli复合运算符,类似于翻转。有了单子,祖父母=父母>=>父母。谢谢。似乎大多数monad教程都没有介绍这个操作符,尽管我已经看过很多次了。再说一次,我可能太聪明了,不利于我自己,而祖父母s=父亲s>>>=父母`mplus`母亲>>=父母很好,但haskell图书馆的作者似乎并不真正接受简单,所以在理解他们的代码之前,我还有一些工作要做:-