基本上,我有一个函数可以通过几个条件检查[1..9]
的每个排列。另外,我有一个函数,它检查列表的总和是否等于数字和切片列表的函数。问题是它返回错误Couldn't match type 'Int' with 'Char'
。它指向列表,如果所有条件都为真,则必须返回哪个函数。
这是代码本身:
intSumList :: Int -> [Int] -> Bool
intSumList _ [] = True
intSumList x (y:ys)
| x == sum (y:ys) = True
| otherwise = False
slice :: Int -> Int -> [Int] -> [Int]
slice from to s = take (to - from + 1)(drop from s)
find :: (Int,Int,Int,Int) -> [Int]
find (x,z,y,s) = checkPerm (x,z,y,s) l
where
l = L.permutations [1..9]
checkPerm (_,_,_,_ ) [] = ""
checkPerm (x,z,y,s) (p:pz)
| intSumList x (slice 1 5 p) && intSumList z (slice 2 6 p) &&
intSumList y (slice 4 8 p) && intSumList s (slice 5 9 p) = p
| otherwise = permutations (x,z,y,s) pz
答案 0 :(得分:1)
当前问题是checkPerm
返回一个类型为[Char]
的空列表,而不是[Int]
,当它获取一个空列表作为其第二个参数时。
但是,checkPerm
基本上是重新实现Data.List.find
。
import qualified Data.List as DL
import Data.Maybe
import Control.Monad
find :: (Int,Int,Int,Int) -> [Int]
find (x,z,y,s) = fromMaybe [] (DL.find p l)
where makePred x lo hi p = intSumList x (slice lo hi p)
p1 = makePred x 1 5
p2 = makePred z 2 6
p3 = makePred y 4 8
p4 = makePred s 5 9
p = liftM4 (&&) p1 p2 p3 p4
l = DL.permutations [1..9]
如果未找到匹配项,则 DL.find
会返回Nothing
,对于匹配列表Just l
,会返回l
。 fromMaybe
将此值转换为空列表或找到的列表。不过,您可以考虑将find
的返回值保留为Maybe [Int]
。