如何在haskell中定义两个列表的奇数和偶数

时间:2015-10-01 10:41:03

标签: haskell

我需要获取列表中的元素并将它们放入haskell中的两个单独的奇数和平均列表中。这是我到目前为止所拥有的。

classEvenOdd :: [Int] -> ([Int], [Int])
classEvenOdd []     = ([] , [])
classEvenOdd (x:xs) =  (even [xs] | odd [xs])

错误如下:

ERROR "new_1.hs":62 - Type error in explicitly typed binding
*** Term           : classEvenOdd
*** Type           : [Int] -> [a]
*** Does not match : [Int] -> ([Int],[Int])

2 个答案:

答案 0 :(得分:1)

你得到的错误源于这一行:

classEvenOdd [] = []

此片段属于

类型
classEvenOdd :: [a] -> [a]

这不是您所声明的类型(classEvenOdd :: [Int] -> ([Int],[Int]))。通过将类型更改为: classEvenOdd [] = ([], [])

但是,即使此问题已解决,代码中也会出现其他错误。您没有将x值保留在列表的头部,因此一旦解决了任何语法问题(因为后面的代码片段中的语法对我来说不熟悉),您将始终以空列表结束!

您应该保留部分结果并在检查输入列表的每个元素时继续传递,或者您应该假设完成子列表xs,然后将结果添加到正确的元素元组。

第二种方法如下:

classEvenOdd :: [Int] -> ([Int], [Int])
classEvenOdd [] = ([], [])
classEvenOdd (x:xs) = let (evens, odds) = classEvenOdd xs in if even x 
                      then (x:evens, odds) 
                      else (evens, x:odds)

然而,由于依赖于每个阶段的完成值,这种方法会泄漏空间(至少没有开启优化)。

更好的方法是将部分结果作为额外参数:

classEvenOdd :: [Int] -> ([Int], [Int])
classEvenOdd [] = ([], [])
classEvenOdd x = go ([], []) x
    where go (e,o) (x:xs) = if even x 
                            then go xs (x:e, o)
                            else go xs (e, x:o)
          go (e,o) [] = (e, o)

答案 1 :(得分:1)

我不太确定您的代码是如何工作的,但我会通过我的方法来完成这项功能。当我想到它时,我想到了这样做:

classEvenOdd :: [Int] -> ([Int],[Int])
classEvenOdd xs = (filter odd xs, filter even xs)

但是这需要将列表过滤两次,从而使执行*所需的时间加倍。因此,我们希望在列表上定义一个函数,将其分类到两个列表中。这听起来像我们想要一个Eithers列表([Either Int Int])。然后可以使用partitionEithers()将列表转换为元组(([Int],[Int]))。

import Data.Either

classEvenOdd' :: [Int] -> ([Int],[Int])
classEvenOdd' xs = partitionEithers (map eitherEvenOdd xs)

eitherEvenOdd :: Int -> Either Int Int
eitherEvenOdd i
 | even i = Right i
 | odd i  = Left i

这也可以point free

完成
import Data.Either

classEvenOdd' :: [Int] -> ([Int],[Int])
classEvenOdd' = partitionEithers.(map eitherEvenOdd)

eitherEvenOdd :: Int -> Either Int Int
eitherEvenOdd i
 | even i = Right i
 | odd i  = Left i

*受非严格性的影响