使用lambda表达式组合



我尝试了一个使用lambda表达式组合的虚拟示例。下面的代码编译,但它不运行时,我尝试(f.g) 3 2

f x = x^2
g x = 5*x
f.g = x -> f(g x)

它给出了这样一个错误:

Ambiguous occurrence `.'
It could refer to
either `Prelude..',
imported from `Prelude' at list3.hs:1:1
(and originally defined in `GHC.Base')
or `Main..', defined at list3.hs:42:3.
谁能告诉我问题出在哪里?

您定义了一个复合操作符与从Prelude导入的并存。定义没有错;当您尝试使用时,问题就出现了,因为编译器无法判断是否有像

这样的内容。
main = print $ f . g $ 10

应该使用前奏中的.Main模块中的.

一个解决方案是简单地明确说明你想要两者中的哪一个。

f . g = x -> f (g x)
main = print $ f Main.. g $ 10

或者一开始就不导入Prelude版本。

{-# LANGUAGE NoImplicitPrelude #-}
import Prelude hiding ((.))
-- Now this is the *only* definition.
f . g = x -> f (g x)
main = print $ f . g $ 10

正如chepner的精彩回答所解释的那样,你的'。点运算符与常规的点运算符冲突。'操作符从Haskell Prelude隐式导入。这就是错误信息的含义。

幸运的是,Haskell编译器支持Unicode字符集,而且它恰好提供了在数学书中看到的适当的函数组成字符,即小数位置8728的'∘'。

这个'°'操作符是NOT(到目前为止)由序曲定义。

因此,下面的代码可以正常工作:
main :: IO ()
main = do
let
-- our own function composition operator:
fna ∘ fnb  =  x -> fna (fnb x)  -- Unicode character #8728 (decimal)
f x    =   x * x
g x    =   5 * x
h      =   f ∘ g  -- composed function
res    =   h 7
putStrLn $ "res = " ++ (show res)

,输出结果1225,如您所料。

最新更新