Haskell两个二元函数的函数组成?

时间:2015-05-13 05:50:04

标签: haskell monads function-composition

我正在20 Intermediate Haskell exercises工作,我被困在练习13上:

-- Exercise 13
-- Relative Difficulty: 6
apple :: (Misty m) => m a -> m (a -> b) -> m b
apple = error "todo"

其中Misty Typeclass基本上是Monad Typeclass,并且实现如下:

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

我满足了我的好奇心,并在网上找到了这个练习的解决方案

apple = banana . flip furry'

哪里有毛茸茸的'是一个实现为

的liftM版本
furry' f mi = banana (\x -> unicorn (f x)) mi

我不明白的是在两个二元函数(即香蕉和翻转的毛茸茸的')上使用函数组合(。),如果有人可以通过对此的评估,我认为这将有所帮助我很多。

1 个答案:

答案 0 :(得分:3)

让我们一步一步开始。提供了jQuery(function($) { $('[data-numeric]').payment('restrictNumeric'); $('.cc-number').payment('formatCardNumber'); $('.cc-exp').payment('formatCardExpiry'); $('.cc-cvc').payment('formatCardCVC'); $.fn.toggleInputError = function(erred) { this.parent('.form-group').toggleClass('has-error', erred); return this; }; $('#payment-form').submit(function(e) { e.preventDefault(); var cardType = $.payment.cardType($('.cc-number').val()); $('.cc-number').toggleInputError(!$.payment.validateCardNumber($('.cc-number').val())); $('.cc-exp').toggleInputError(!$.payment.validateCardExpiry($('.cc-exp').payment('cardExpiryVal'))); $('.cc-cvc').toggleInputError(!$.payment.validateCardCVC($('.cc-cvc').val(), cardType)); $('.cc-brand').text(cardType); if (!$('.form-group').hasClass('has-error')) { return false; } }); }); 类型类:

Misty

class Misty m where banana :: (a -> m b) -> m a -> m b unicorn :: a -> m a 已经解决了这些练习中的早期问题:

furry'

现在你必须定义furry' :: Misty m => (a -> b) -> m a -> m b furry' f mi = banana (\x -> unicorn (f x)) mi 函数:

apple

现在尝试按照类型签名。假设你这样定义apple :: (Misty m) => m a -> m (a -> b) -> m b apple = error "todo"

apple

现在您能看到上述类型与apple xs ys xs will have type of m a ys will have type of m (a -> b) 之间的关系吗?所以 您必须以某种方式将furry'xs应用于ys现在,因为它已经 您可以使用furry'中已有的第二个参数m a xs获取它:

flip

因此,您可以将flip furry' :: m a -> (a -> b) -> m b应用于它的第一个参数,您将拥有 以下类型签名:

xs ------- 公式 1

有关如何应用(flip furry') xs :: (a -> b) -> m b的任何猜测?尝试统一上述类型 带有ys的第一个参数的签名:

那会给你:

banana

因此,a ~ (a -> b) m b ~ (m b) 的类型签名从

转换而来
banana

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

现在从banana :: ((a -> b) -> m b) -> m (a -> b) -> m b 我们知道Equation (1)类型签名匹配 (flip furry') xsbanana的第一个参数与第二个参数匹配 ys。这为您提供了banana

的定义
apple

可以无点的方式表达为:

apple :: (Misty m) => m a -> m (a -> b) -> m b
apple xs ys = banana ((flip furry') xs ) ys