简体   繁体   English

Haskell,使用 function 和列表推导

[英]Haskell, using function with list comprehensions

I am trying to accomplish the following:我正在尝试完成以下任务:

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)]

Specifically, I'm trying to run a function, take the result [[int]] , then map another function onto that result.具体来说,我正在尝试运行 function,获取结果[[int]] ,然后 map 另一个 function 到该结果上。 Which haskell appearantly abhors, and I need to use some combination of "lambda functions" and other wizardry I cant read or comprehend at all to get this chugging along.哪个 haskell 显然令人厌恶,我需要结合使用“lambda 函数”和其他我根本无法阅读或理解的魔法来实现这一点。

Is there any simple way to do this that wont require a 7 month course in mathematical function syntax?有没有什么简单的方法可以做到这一点,不需要 7 个月的数学 function 语法课程?

As mentioned above, the result, board, is [[int]], and sequence is simply [int].如上所述,结果 board 是 [[int]],sequence 就是 [int]。

The errors it produces are它产生的错误是

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.

It seems you have written all your functional code correctly but have not correctly specified your type signatures.看来您已经正确编写了所有功能代码,但没有正确指定类型签名。 trimBoard expects a Board as its first argument, but you have passed it c which is a single row. trimBoard需要一个Board作为它的第一个参数,但是您已经将它传递给它c ,它是单行。

What you may be complaining about is that trimBoard ought to work perfectly well if you pass it a single row instead of a complete board.您可能抱怨的是,如果您将trimBoard传递给单行而不是完整的电路板,它应该可以很好地工作。 And indeed it does, you just need to learn how to say so:确实如此,您只需要学习如何说:

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

That it, trimBoard takes a list of any type, and an Int , and returns a list of that same type.也就是说, trimBoard接受任何类型的列表和一个Int ,并返回相同类型的列表。 Now you are not restricted to passing lists of lists of Int , and everything works fine.现在,您不仅限于传递Int列表的列表,而且一切正常。

You could also have omitted the type signature of trimBoard and Haskell would have inferred this one, which is the most general one.您也可以省略 trimBoard 的类型签名, trimBoard会推断出这个,这是最通用的一个。 (But it is good to write type signatures and learn how to do so -- in fact, with practice, this becomes an invaluable tool that I miss dearly in other languages). (但是编写类型签名并学习如何这样做是件好事——事实上,通过实践,这成为我在其他语言中非常怀念的无价工具)。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM