如何使用map来概括函数

时间:2017-10-10 05:51:07

标签: haskell

我正在尝试设计一个Haskell程序来构建一个游戏理论树,通过反复播放指定次数的基础游戏(小G)来创建游戏(大写字母G)。

下面的 foo 函数通过将一轮的结果(或支付)添加到基础游戏的每个结果/支付来正常工作。一个主要的限制是基础游戏永久设置为有三个结果。

foo'函数(不起作用)应该是 foo 函数的泛化。这是通过使用map函数和表示基本游戏的值列表来模仿 foo 函数。

data MyTree a = Root a [MyTree a] | Branch a [MyTree a] | Leaf a | EmptyNode deriving Show

x1:: Integer
x1 = 1

x2 :: Integer
x2 = 25

x3 :: Integer
x3 = 100

foo :: [Integer] -> MyTree [Integer] 
foo [r, a] 
    | r == 0      = Leaf   [a] 
    | a == 0      = Root   [a] [foo [r-1, a+x1], foo [r-1, a+x2], foo [r-1, a+x3]]
    | otherwise   = Branch [a] [foo [r-1, a+x1], foo [r-1, a+x2], foo [r-1, a+x3]]

lst = [x1, x2, x3]

foo' :: [Integer] -> MyTree [Integer] 
foo' [r, a] 
    | r == 0      = Leaf   [a] 
    | a == 0      = Root   [a] map (foo'.(\y ->[r-1, y]).(\x -> a+x)) lst
    | otherwise   = Branch [a] map (foo'.(\y ->[r-1, y]).(\x -> a+x)) lst

以下错误显示两次(一个用于 a == 0 行,另一个用于否则线)。我只列出一次,因为一旦我知道如何修复错误,我就可以修复它的副本。

我得到的错误信息是(a)和(b):

Couldn't match expected type ‘([Integer] -> MyTree [Integer]) -> [[Integer]] -> MyTree [Integer]’with actual type ‘MyTree [Integer]’


Couldn't match expected type ‘[MyTree [Integer]]’with actual type ‘(a0 -> b0) -> [a0] -> [b0]’

我的问题是:如何获得与预期输入匹配的实际输入?我花了很多天时间研究语法和谷歌搜索解决方案。

1 个答案:

答案 0 :(得分:2)

问题正是编译器所说的:

  

函数'Root'应用于四个参数,         但它的类型'[整数] - > [MyTree [Integer]] - > MyTree [整数]'         只有两个

这是因为编译器假定[a]map(foo'.(\y ->[r-1, y]).(\x -> a+x))lst是函数Root的四个独立参数。

可以使用$来修复它,它设置评估的优先级

foo' :: [Integer] -> MyTree [Integer] 
foo' [r, a] 
    | r == 0      = Leaf   [a] 
    | a == 0      = Root   [a] $ map (foo'.(\y ->[r-1, y]).(\x -> a+x)) lst
    | otherwise   = Branch [a] $ map (foo'.(\y ->[r-1, y]).(\x -> a+x)) lst

或者,因为它可以移动到一个单独的函数中(可能genList名称不合适,当然你可以组成一个更好的名称):

foo' :: [Integer] -> MyTree [Integer]
foo' [r, a]
    | r == 0      = Leaf   [a]
    | a == 0      = Root   [a] genList
    | otherwise   = Branch [a] genList
    where genList = map (foo'.(\y ->[r-1, y]).(\x -> a+x)) lst