Haskell函数有2个参数,但在定义中没有

时间:2016-05-16 18:43:42

标签: function haskell parameters pointfree

我是Haskell的新手,我正在尝试理解在Haskell中创建的游戏(tic tac toe)。我知道如果一个函数需要n个参数,那么你必须在函数定义中提供n个参数。例如:

f :: Int -> Int -> String
f a b = "This function makes no sense" 

但是在这个Haskell脚本中有一个函数需要两个参数,但在定义中它没有。当然,它正在发挥作用,但我似乎无法弄清楚原因。

import Data.Map qualified as M
type Board = M.Map (Int, Int) Marker
data Marker = X | O | Blank deriving Eq

getMarker :: Board -> (Int, Int) -> Marker
getMarker = flip $ M.findWithDefault Blank

关于这个函数的作用的任何想法,更重要的是,为什么它有效(你可以看到getMarker在最后一行占用0个参数)?

2 个答案:

答案 0 :(得分:4)

误解在于:

  

...(你可以看到getMarker在最后一行占用0个参数)......

令你困惑的是partial application

getMarker :: Board -> (Int, Int) -> Marker
getMarker = flip $ M.findWithDefault Blank

最后一行实际告诉你的是getMarker flip $ M.findWithDefault Blank

或者,更准确地说,getMarker求值为应用于 getMarker参数的声明类型的函数。

答案 1 :(得分:1)

你有getMarker :: Board -> (Int, Int) -> Marker,所以它被称为

getMarker board pos

由于你有getMarker = flip $ M.findWithDefault Blank,这相当于:

(flip $ M.findWithDefault Blank) board pos

扩展$

(flip (M.findWithDefault Blank)) board pos

功能应用程序是左关联的,因此(f x) y等同于f x y

flip (M.findWithDefault Blank) board pos

flip f x y相当于f y x,因此表达式等于:

(M.findWithDefault Blank) pos board

再次,感谢函数应用程序的左关联性:

M.findWithDefault Blank pos board

这是明智的。