Haskell,将函数与列表推导一起使用

时间:2019-11-04 07:07:38

标签: haskell

我正在尝试完成以下任务:

slice :: Int -> Int -> [a] -> [a]
slice from to xs = take (to - from + 1) (drop from xs)

trimBoard :: Board -> Int -> Board
trimBoard s y = slice ((y*3)) (((y+1)*3)-1) s

getBox :: Board -> Int -> Int -> [Sequence]
getBox s y x = [ (trimBoard c x) | c <- (trimBoard s y)]

具体来说,我正在尝试运行一个函数,获取结果[[int]],然后将另一个函数映射到该结果。哪个haskell似乎很令人讨厌,我需要使用“ lambda函数”和我完全无法阅读或理解的其他向导的某种组合来实现这一点。

有没有简单的方法可以不需要7个月的数学函数语法课程?

如上所述,结果board是[[int]],而序列只是[int]。

它产生的错误是

sudoku.hs:139:19: error:
    • Couldn't match type ‘[Int]’ with ‘Int’
      Expected type: Sequence
        Actual type: Board
    • In the expression: (trimBoard c x)
      In the expression: [(trimBoard c x) | c <- (trimBoard s y)]
      In an equation for ‘getBox’:
          getBox s y x = [(trimBoard c x) | c <- (trimBoard s y)]

sudoku.hs:139:29: error:
    • Couldn't match type ‘Int’ with ‘[Int]’
      Expected type: Board
        Actual type: Sequence
    • In the first argument of ‘trimBoard’, namely ‘c’
      In the expression: (trimBoard c x)
      In the expression: [(trimBoard c x) | c <- (trimBoard s y)] Failed, modules loaded: none.

1 个答案:

答案 0 :(得分:5)

似乎您已正确编写了所有功能代码,但未正确指定类型签名。 trimBoard期望将Board作为其第一个参数,但是您已经将它传递给了c,它是一行。

您可能会抱怨的是,如果您将trimBoard传递给一行而不是一块完整的木板,它应该表现得很好。确实如此,您只需要学习怎么说:

trimBoard :: [a] -> Int -> [a]

trimBoard接受一个 any 类型的列表和一个Int,然后返回相同类型的列表。现在,您不仅可以传递Int的列表列表,而且一切正常。

您还可以省略trimBoard的类型签名,Haskell可以推断出这是最通用的一个。 (但是写类型签名并学习如何做是很好的-实际上,通过实践,这成为了我用其他语言非常想念的无价工具)。