如何定义将三个函数的组合应用于值的函数?

时间:2015-02-21 05:09:16

标签: haskell function-composition

我有以下问题,我不知道从哪里开始:

  

写一个函数

trifecta :: (a -> b) -> (b -> c) -> (c -> d) -> a -> d
     

它接受3个函数并将它们组成一个函数,该函数接受一个值并产生一个值。在编写测试时,请包含一些具有不同类型的测试。

我该怎么做?

2 个答案:

答案 0 :(得分:3)

你曾经使用过djinn吗?它是直觉主义命题逻辑的theorem prover。简单来说,给定simple type signature它会生成满足该类型的Haskell表达式。

您可以使用命令cabal install djinn安装djinn。之后运行djinn命令行程序:

$ djinn
Welcome to Djinn version 2011-07-23.
Type :h to get help.
Djinn> trifecta ? (a -> b) -> (b -> c) -> (c -> d) -> a -> d
trifecta :: (a -> b) -> (b -> c) -> (c -> d) -> a -> d
trifecta a b c d = c (b (a d))

正如您所看到的,给定查找函数证明trifecta ? (a -> b) -> (b -> c) -> (c -> d) -> a -> d的命令,djinn提出了解决方案:

trifecta :: (a -> b) -> (b -> c) -> (c -> d) -> a -> d
trifecta a b c d = c (b (a d))

希望如果你使用djinn,你将能够自己找到琐碎问题的答案,并通过研究输出,你应该能够理解函数式编程的基本要素。

答案 1 :(得分:1)

要求您编写一个函数trifecta,该函数接受一个函数,该函数采用a类型的值,返回类型为b的值,写为(a -> b),函数获取类型为b的值并返回类型c的值,写为(b -> c),最后返回一个类型为c的函数,并返回值为输入d。如果您依次应用这些函数,则可以看到有一种方法可以通过使用所有这三个函数从类型d的值中获取类型a的值。

如果您认为trifecta的实施正确,则应该有效:

Prelude> trifecta show reverse read 15 :: Double
51.0

将值15转换为字符串(通过show),然后转换为reverse d,获得“51”,最后转换为浮点变量(read)。在这种情况下,类型aIntegerbStringcStringd为{{ 1}},所以这并不能解决让所有类型完全不同的任务,因为Doubleb属于同一类型。