与 lambda 表达式组合 haskell

Composition with lambda expressions haskell

我尝试了一个使用 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

应该使用 Prelude 中的 .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 隐式导入的运算符。这就是错误消息的意思。

幸运的是,Unicode 字符集被 Haskell 编译器支持,它恰好提供了数学书上看到的正确的函数组合字符,即十进制的 '∘'位置 8728.

而这个 '∘' 运算符是 NOT(目前)由 Prelude 定义。

因此,以下代码可以正常工作:

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,如您所料。