简体   繁体   中英

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. 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.

Is there any simple way to do this that wont require a 7 month course in mathematical function syntax?

As mentioned above, the result, board, is [[int]], and sequence is simply [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.

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. 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. Now you are not restricted to passing lists of lists of Int , and everything works fine.

You could also have omitted the type signature of trimBoard and Haskell would have inferred this one, which is the most general one. (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).

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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