我有此代码:
getLengthOfMissingArray :: Maybe [Maybe [Int]] -> Maybe Int
getLengthOfMissingArray maybelist = do
ns <- maybelist
getMissing ns
getMissing :: [Maybe [Int]] -> Maybe Int
getMissing maybelist
| any (==Nothing) maybelist = Nothing
| any (==Just []) maybelist = Nothing
| otherwise = Just (sumn mx - sumn (mn - 1) - sum l0)
where
l0 = map length (catMaybes maybelist)
(mn,mx) = (minimum l0, maximum l0)
sumn n = n * (n + 1) `quot` 2
这是Haskell的译文:
https://www.codewars.com/kata/length-of-missing-array
现在可以了,但是我有两个问题:
我想让getMissing成为:
getMissing :: [[Int]] -> Int
然后仅在另一个函数中使用该函数,但我不知道如何在Maybe
的{{1}}上使用该函数。
第二,我尝试简单地做:
Maybe
但是,当我尝试在测试用例上使用QuickCheck时,Haskell会生成错误:
getMissing :: Eq a => [Maybe [a]] -> Maybe Int
getLengthOfMissingArray :: Eq a => Maybe [Maybe [a]] -> Maybe Int
可以,但是会产生类型错误:
getLengthOfMissingArray (Just [ Nothing, Just [ 4, 5, 1, 1 ], Just [ 1 ],
Just [ 5, 6, 7, 8, 9 ] ]) `shouldBe` Nothing
我猜没有实际的getLengthOfMissingArray (Just [Just []]) `shouldBe` Nothing
会有一个问题,因为如果我只是尝试在a
上运行它,还会产生相同的类型错误:
”由于使用了“ getLengthOfMissingArray”而产生的歧义类型变量“ a0” 阻止解决约束“(Eq a0)”。”
答案 0 :(得分:4)
sequence :: [Maybe a] -> Maybe [a]
将帮助您使[Maybe [Int]]
适应[[Int]]
。
join :: Maybe (Maybe a) -> Maybe a
也可能有用。
sequence和join都有更通用的类型-我写了它们,因为我希望您在这里使用它们。
当您将多态值传递给参数中具有多态性的函数时,您将看到“歧义类型变量”错误。要实际运行GHC功能,需要使用特定的类型,而它不会选择-您需要。由于您希望getLengthOfMissingArray
保持多态,因此可以在测试用例中添加类型签名以指定测试的运行方式。
答案 1 :(得分:0)
感谢伯吉(以及cw上的dramforever):
getLengthOfMissingArray :: Eq a => Maybe [Maybe [a]] -> Maybe Int
getLengthOfMissingArray maybelist = do
list <- maybelist
ns <- sequence list
getMissing ns
getMissing :: Eq a => [[a]] -> Maybe Int
getMissing list
| any (==0) l0 = Nothing
| otherwise = Just $ sumn mx - sumn (mn - 1) - sum l0
where
l0 = map length list
(mn,mx) = (minimum l0, maximum l0)
sumn n = n * (n + 1) `quot` 2
并调整测试:
getLengthOfMissingArray (Nothing :: Maybe [Maybe [Int]]) `shouldBe` Nothing