Haskell函数示例

时间:2014-03-06 18:40:02

标签: haskell

有人可以举例说明具有以下签名的函数:

f :: a -> b -> (a -> b)

f接受两个类型为a和b的参数,并返回一个函数,该函数接受类型为a的参数并返回类型为b的元素。

我们的老师今天给了我们这个额外的练习,并说它真的很难。我尝试使用lambda表达式编写它,但我失败了。

这是一项非常有趣的练习,如果有人知道该怎么做,请回答这个问题。谢谢!

5 个答案:

答案 0 :(得分:5)

首先,我们可以省略括号,a -> b -> (a -> b)

相同
a -> b -> a -> b

(这是因为currying

现在看看这个签名。我们得到了以下输入:

  • a
  • 类型的两件事
  • b
  • 类型的一件事

我们需要返回b类型的内容。但是现在看,只有一种方法可以做到这一点(如果我们暂时忽略undefined),因为我们只得到一个b类型的值!我们只是返回那个值:

f :: a -> b -> a -> b
f _ b _ = b -- We ignore both values of type a, because we cannot do anything with a's

所以上面我说只有一个解决方案,如果我们忽略undefinederror ...let v = v in v和类似的(那些被称为bottom值,因为它们要么崩溃程序或在评估时不会终止)。你能找到一个使用其中一个的定义吗?


修改

如评论中所述,此函数实际上具有更通用的类型。我假设练习是找到一个可以该类型的函数,而不是一个推断类型是给定类型的函数。如果那不是您想要的,请参阅@bheklilr's answer

如果您对简短但难以理解的定义感兴趣,请参阅codegolf上的类似问题

答案 1 :(得分:5)

类型a -> b -> a -> b的函数可以表示为

f a1 b a2 = let xs = [a1, a2] in b

由于这会强制a1a2具有相同的类型,以便位于同一列表中。 xs的值刚刚被丢弃,然后我们返回b


另一个是

g a1 b a2 = let x = g a2 b a1 in b

根本不使用列表,而是使用非常类似的技术来欺骗编译器统一a1a2的类型。

答案 2 :(得分:3)

f a' b a'' = const b (asTypeOf a' a'')

答案 3 :(得分:3)

最近出现了这样的问题。由于没有关于返回值的其他要求,您可以返回给定的b,并忽略类型a的两个值。 b->a->bconst。所以f _ = const是最短的函数,它将忽略第一个和第三个参数,并返回与第二个参数相同类型的值。然而,它并没有将第一个和第三个参数的类型绑定为相同。我们可以通过将它们作为f的相同参数来提供。

最简单的方法之一是通过组合:f _ = (.f).const现在因为第三个参数作为第一个参数被输入f,这些参数的类型将是相同的。

答案 4 :(得分:2)

f a b c = const b (asTypeOf c a)      -- answer by md2perpe
        = const b (f c)
        = const b . f $ c
        = ((. f) . const) b c         -- answer by Sassa NF

这是(递归)定义,而不是表达式。因此,如果您想要使用此签名找到表达式

f  = const ((. f) . const) 
   = (const . (. const)) (. f)
   = ((const . (. const)) . flip (.)) f
   = fix ((const . (. const)) . flip (.))

fix来自Data.FunctionasTypeOf不是原始的组合子,因为它本身是使用显式类型签名asTypeOf :: a -> a -> a ; asTypeOf = const定义的。建议使用[]

f a b c = const b ( (a:) . (c:) )

1

f   = flip ((.) . const) . (. (:)) . (.) . (:)

选择毒药。 :)

1 由于某种原因,lambdabot在这里产生了错误的const const(错误的一般签名)。我通过运行产生@pl \a b c -> const const b ( (a:) . (c:) )的{​​{1}}来欺骗它。