[英]Haskell about recursion in list function
我正在尝试创建一个函数(我是haskell中的新手),该函数需要两个列表并返回一个列表。 该列表应具有第一个列表的所有元素,这些元素不在第二个列表中,所有第二个列表的元素不在第一个列表中。
因此: func [3,2,1,4] [2,5,1]
应该返回[3,4,5]
我认为我的《规范》朝着正确的方向发展,但是其中的一个大错误是。
func :: [Int] -> [Int] -> [Int]
func [] a = a
func a [] = a
func (x:xs) (y:ys) | elem x (y:ys) = filter (/=x) (y:ys)
| otherwise = func ys xs
假装对这方面的问题没有任何经验或对base
的功能非常熟悉,我将重新编写您的问题说明以描述我们想要的操作,并向您展示如何解决该问题:
在两个列表上获得
fun
的结果是:第一个列表中的所有元素不在第二个列表中,第二个列表中的所有元素不在第一个中。
要开始用代码表示,请将“ is”替换为=
:
func l1 l2 = (elementsOfFirstNotInSecond l1 l2) ++(elementsOfFirstNotInSecond l2 l1)
现在我们需要实现elementsOfFirstNotInSecond
,所以让我们从单词开始:
elementsOfFirstNotInSecond
两个名单是:如果l1
是空列表,则空单,否则,如果头l1
(我们将其称为“x
”)是其成员l2
则x
consed到elementsOfFirstNotInSecond
尾部的l1
和l2
。 否则(如果x
不在l2
),则只是l1
和l2
尾部的elementsOfFirstNotInSecond
看看是否可以使用尚未实现的函数将其转换为haskell(例如,您可能要使用( isAMemberOf :: Int -> [Int] -> Bool
),然后重复该过程。
输出顺序重要吗?
如果没有,您可以只使用Data.List
列表差异(\\\\)
Prelude > import Data.List
Prelude Data.List> as = [3,2,1,4]
Prelude Data.List> bs = [2,5,1]
Prelude Data.List> notinSec = as \\ bs
Prelude Data.List> notinFst = bs \\ as
Prelude Data.List> ans = notinSec ++ notinFst
Prelude Data.List> ans
[3,4,5]
由于您想要递归并且是haskell的新手,因此解决方案(朝您的方向移动)将类似于
func (x:xs) (y:ys) | elem x (y:ys) && (not (elem y (x:xs))) = func xs (filter (/=x) (y:ys))
| (not (elem x (y:ys))) && (elem y (x:xs)) = func (filter (/=y) (x:xs)) ys
| (elem x (y:ys)) && (elem y (x:xs)) = func (filter (/=y) (xs)) (filter (/=x) (ys))
| otherwise = x : y : (func xs ys)
但是您可以看到在学习路径的后期,这是多么的丑陋和混乱。 我建议您使用更简单明了的替代方法。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.