我尝试了一个使用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,如您所料。