简体   繁体   English

Haskell Maybe /参数多态

[英]Haskell Maybe/Parametric Polymorphism

I have this code : 我有这个代码:

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

Which is a Haskell translation of this : 这是Haskell的译文:

https://www.codewars.com/kata/length-of-missing-array https://www.codewars.com/kata/length-of-missing-array

Now it works, however I have two issues : 现在可以使用,但是我有两个问题:

  • it is kind of fugly 这有点丑陋
  • it should work on any list, not just int's 它应该在任何列表上工作,而不仅仅是int的

I would like to have getMissing just be : 我希望getMissing只是:

getMissing :: [[Int]] -> Int 

And then just use that function inside of the other one, but I don't know how to utilize that function on the Maybe of a Maybe . 然后仅在另一个函数中使用该函数,但我不知道如何在MaybeMaybe使用该函数。

Second, I tried simply doing : 其次,我尝试简单地做:

getMissing :: Eq a => [Maybe [a]] -> Maybe Int 
getLengthOfMissingArray :: Eq a => Maybe [Maybe [a]] -> Maybe Int 

But then Haskell generates errors when I try to use QuickCheck on test cases like : 但是当我尝试对以下测试用例使用QuickCheck时,Haskell会生成错误:

getLengthOfMissingArray (Just [ Nothing, Just [ 4, 5, 1, 1 ], Just [ 1 ],
                                Just [ 5, 6, 7, 8, 9 ] ])     `shouldBe` Nothing

That works, but this generates type errors : 可以,但是会产生类型错误:

getLengthOfMissingArray (Just [Just []])                      `shouldBe` Nothing

I guess without an actual a there there's an issue because if I just try to run it on a Nothing it also generates the same type error: 我想不管有没有a有有一个问题,因为如果我只是尝试在运行它Nothing它也产生了同样类型的错误:

"Ambiguous type variable 'a0' arising from a use of 'getLengthOfMissingArray' prevents the constraint '(Eq a0)' from being solved." “由于使用'getLengthOfMissingArray'而产生的歧义类型变量'a0'阻止了约束'(Eq a0)'的求解。”

sequence :: [Maybe a] -> Maybe [a] will help you adapt your [Maybe [Int]] to [[Int]] . sequence :: [Maybe a] -> Maybe [a]将帮助您将[Maybe [Int]][[Int]]

join :: Maybe (Maybe a) -> Maybe a might also be useful. join :: Maybe (Maybe a) -> Maybe a也可能有用。

Both sequence and join have more general types - I wrote them as I expect you will use them here. 序列连接都具有更通用的类型-我写了它们,因为我希望您在这里使用它们。

You will see "Ambiguous type variable" errors when you pass a polymorphic value to a function that is polymorphic in its argument. 将多态值传递给参数中多态的函数时,将看到“歧义类型变量”错误。 To actually run the function GHC needs to use a specific type, and it won't choose - you need to. 要实际运行GHC功能,需要使用特定的类型,而它不会选择-您需要。 Since you want getLengthOfMissingArray to remain polymorphic, you can add a type signature to the test case to specify how the tests should run. 由于您希望getLengthOfMissingArray保持多态,因此可以在测试用例中添加类型签名以指定测试的运行方式。

Thanks to bergey (and dramforever on cw) : 感谢bergey(和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

And adjusting the tests : 并调整测试:

getLengthOfMissingArray (Nothing :: Maybe [Maybe [Int]]) `shouldBe` Nothing

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

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