haskell - 无法将预期类型“[a1]”与实际类型“([a1],[a1])”匹配
问题描述
我是使用 Haskell 编码的新手,并且一直坚持我的教授希望我们编写的代码。我应该将一个列表处理成一对列表,如下所示:
deal [1,2,3,4,5,6,7] = ([1,3,5,7], [2,4,6])
但我在我的“xs”和“ys”上都收到了这个错误
* Couldn't match expected type `[a1]'
with actual type `([a1], [a1])'
* In the expression: deal xs
In an equation for `xs': xs = deal xs
In an equation for `deal':
deal (x : y : xs : ys)
= (x : xs, y : ys)
where
xs = deal xs
ys = deal ys
* Relevant bindings include xs :: [a1] (bound at lab2.hs:16:17)
|
| xs = deal xs
| ^^^^^^^
这是我的代码:
deal :: [a] -> ([a],[a])
deal [] = ([], [])
deal [x] = ([x], [])
deal (x:y:xs:ys) = (x:xs,y:ys)
where
xs = deal xs
ys = deal ys
解决方案
这是合乎逻辑的,因为在这里你的deal xs
anddeal ys
将返回,给定签名一个 2 元组列表,并且xs
具有 type [a]
。请注意,通过使用相同的名称,您在这里做了一个递归表达式,这将不起作用。多次使用相同的名称不是一个好主意。如果您打开警告,编译器通常会对此发出警告。
您可能想要调用列表deal
的rest
,然后检索您用作尾部的两个列表:
deal :: [a] -> ([a],[a])
deal [] = ([], [])
deal [x] = ([x], [])
deal (x:y:rest) = (x:xs, y:ys)
where (xs, ys) = deal rest
或者我们可以利用(***) :: a b c -> a b' c' -> a (b, b') (c, c')
:
import Control.Arrow((***))
deal :: [a] -> ([a],[a])
deal [] = ([], [])
deal [x] = ([x], [])
deal (x:y:rest) = ((x:) *** (y:)) (deal rest)
另一种方法是每次交换元组,并附加到另一边:
import Control.Arrow(first)
import Data.Tuple(swap)
deal :: [a] -> ([a],[a])
deal [] = ([], [])
deal (x:xs) = first (x:) (swap (deal xs))
因此,我们可以将其定义为一种foldr
模式:
import Control.Arrow(first)
import Data.Tuple(swap)
deal :: Foldable f => f a -> ([a],[a])
deal [] = foldr ((. swap) . first . (:)) ([], [])
这给了我们预期的结果:
Prelude> deal [1,2,3,4,5,6,7]
([1,3,5,7],[2,4,6])
推荐阅读
- amazon-web-services - SNS - 具有 lambda 处理的 SQS 扇出
- nginx - 如何针对自定义 URI 运行 Luigi 服务器
- reactjs - 使用 React、Jest、Redux 和 Thunk 进行无限循环测试
- javascript - 当我在本地运行云功能模拟器时无法运行更新的代码
- javascript - 在 Array Javascript 中的每个对象上运行函数
- instagram - 是否可以获取有关他人个人资料的信息?(Instagram API)
- c - 我试图用 C 制作一个井字游戏,但我不知道如何让 puts() 打印出一个字符
- python - 尝试从函数分配时全局变量不起作用
- javascript - 在 JavaScript 中导入 Azure 密钥保管库模块的问题
- java - Firebase 依赖项没有出现?