Haskell编写你的(。)函数版本

时间:2016-06-03 23:11:21

标签: haskell

有人可以帮我在Haskell中编写自己的(。)函数版本吗? 从这篇文章Haskell write your version of a ($) function我知道如何确定这个函数的类型,但我的身体仍然存在问题。 我也不知道为什么ghci拒绝使用名称(..)。

 ($$$) :: (b -> c) -> (a -> b) -> a -> c 
 ($$$) f (g x) = ((f g) $) x
 infixr 9 $$$

我的另一个想法就是这个:

($$$) :: (b -> c) -> (a -> b) -> a -> c 
($$$) f (g x) = map (f) (g x)
infixr 9 $$$

错误消息显示“模式中的解析错误:g”。

3 个答案:

答案 0 :(得分:5)

来自签名:

($$$) :: (b -> c) -> (a -> b) -> a -> c

你的功能需要3个参数。所以我会开始:

($$$) f g x = ...
      | |  \
      | \   a
      |  \
      |   a->b
    b->c

<强>更新

这种定义($$$)的尝试不起作用:

($$$) (f g) x = ...

它说($$$)需要两个参数。我开始定义($$$)的方式说该函数有三个参数。

答案 1 :(得分:2)

非常感谢您的耐心等待。我使用括号,我不应该。我仍然将查看所有内容(包括数学运算符)作为一个函数。现在(。)的想法很清楚。

($$$) :: (b -> c) -> (a -> b) -> a -> c 
($$$) f g x =  f(g x)
infixr 9 $$$

答案 2 :(得分:2)

你是来自Lisp吗?你似乎仍然在各地假设列表......

正如我在另一个帖子中所说,列表与此任务无关,因此(:)foldrmap都不可能在这里有用。

更重要的是,定义左侧(g x)的出现没有意义。 (这不是一个列表,但显然你认为它应该是一种“参数列表”)。

事实上, 可以 un - curried形式以这种方式定义($$$)

($$$) :: (b->c) -> (a->b, a) -> c
($$$) f (g, x) = ...

......这与更优雅的

完全相同
f $$$ (g, x) = ...

在这种情况下,你有一个参数 tuple (g, x),它或多或少等同于一个Lisp列表。

在Haskell中,我们喜欢编写curried函数。签名

($$$) :: (b -> c) -> (a -> b) -> a -> c

实际上被解析为

($$$) :: (b -> c) -> ( (a -> b) -> (a -> c) )

因此,定义这样一个函数的方法是,在最基本的层面

($$$) = \f -> (\g -> (\x -> ... ))

可以简写为

($$$) f g x = ...

(f $$$ g) x = ...

在实际的定义部分中,您应该同样掌握事物的实际解析方式。正如您现在所知,合成运算符可以定义为

($$$) f g x = f(g(x))

事实上,这里只需要外括号:首选形式是

($$$) f g x = f (g x)

或确实

($$$) f g x = f $ g x

如果某个表达式中出现g x(f g)之类的内容,则始终表示左侧函数应用于右侧参数。对于f g这没有意义,因为虽然f是一个函数,但它不能将另一个函数作为其参数,只能使用此类函数的 result 。好吧,要获得这样的结果,您需要将g应用于参数!