在Haskell中实现签名

时间:2013-06-21 16:19:37

标签: haskell ghci

我有以下函数签名,并希望实现实现它的haskell函数。

method :: (a -> (a -> b)) -> (a -> b)

即使我尝试了各种方法,但我似乎错过了一个起点。我想我可以用(>> =)这样的专长做到这一点,但我不是很确定。由于我对haskell相当新,我甚至不确定如何输出函数而不是像Int或Bool这样的值。

1 个答案:

答案 0 :(得分:5)

让我们用“洞穴驱动的开发”来解决这个问题。我们想要定义method,它是最高级别的函数。我们使用lambdas创建函数,因此我们可以从那里开始并留下一些漏洞。

method = \f     ->     #{1}

我们知道f :: (a -> (a -> b))和我们的洞#{1} :: (a -> b)。我们需要以某种方式使用f来创建#{1}类型的内容。由于我们现在想要另一个函数#{1},让我们使用另一个lambda

method = \f     ->     \a      ->     #{2}

现在a :: a#{2} :: b。我们需要使用bf类型af :: (a -> (a -> b))生成a :: a。希望这一点变得清晰,但让我们继续分解它。

类型表示法具有函数箭头(->)是右关联的约定,因此每当我们看到a -> (b -> c)时,我们都可以将其视为a -> b -> c。此外,我们在两个参数函数(如a -> b -> c)和函数(a, b) -> c的函数之间具有等价性。这个等价正好是curry / uncurry,但在我们的案例中它很有用。

让我们通过ff' :: (a, a) -> b重写为等效函数f' (a, b) = f a b。鉴于我们总是可以使用“对角线”函数diag :: a -> (a,a)来创建同质对,我们就完成了。我们可以使用f'从任何b创建(a,a),我们可以使用diag从任何(a, a)创建a。我们想要一个b,我们有一个a

method = \f     ->     \a      ->     f' (diag a)
  where
    f' (a, b) = f a b
    diag a    = (a, a)

method f a = f a a

因此,您可能会将method视为缩小某个更通用的功能,而不仅仅是diagonals。使其更加清晰的类型签名使用我们的f'技巧:

method :: ((a, a) -> b) -> (a -> b)
method f' a = f' (a, a)