Haskell 列出没有账户的国家保险号码

Haskell 列出没有账户的国家保险号码,haskell,Haskell,我试图列出一些不属于特定银行的数字 这是我的密码 类型 银行 这是我的代码,用来检查NI是否不在银行 bankFree :: Pop -> Market -> Pop bankFree [] x = [] bankFree x [] = error "No Banks selected" bankFree x [[]] = [] bankFree (x:xs) [[],((n,a,b):ys)] = if x == n then bankFre

我试图列出一些不属于特定银行的数字

这是我的密码

类型

银行

这是我的代码,用来检查NI是否不在银行

    bankFree :: Pop -> Market -> Pop
    bankFree [] x = []
    bankFree x [] = error "No Banks selected"
    bankFree x [[]] = []
    bankFree (x:xs) [[],((n,a,b):ys)] = if x == n then bankFree (xs) [[],ys]
                                else x : bankFree xs [[],ys]
    bankFree x [[],[]] = []
    bankFree (x:xs) (((n,a,b):ys):zs) = if x == n then bankFree (xs) ((ys):zs)
                                else if x /= n then x : bankFree xs ((ys):zs)
                                else bankFree (xs) zs
如果我经营无银行上合组织[rbs,clyde],应该显示的是[11,12,13,15,16,18,20],但接下来出现的是[2..20]

我不知道我做错了什么,也不知道该如何处理,因此我们非常感谢您在这件事上提供的任何帮助。

正如我在中所建议的,您在这件事上遇到如此多困难的原因是您没有有效地将问题分解成更小的部分,而且,您没有使用标准的实用程序函数来管理列表。你试图一次咬下太大的一块,这使得它很难解决

因此,您希望将您的问题分解为易于自己解决的子部分,然后将这些子部分组合到大问题的大解决方案中:

import Data.List (any)

type Market = [Bank]
type Bank = [Person]
data Person = Person { ni :: NI, age :: Age, balance :: Balance } 
    deriving (Eq, Show)

bankFree :: Pop -> Market -> Pop
bankFree pop banks = filter checkBanks pop
    where checkBanks n = not (any (bankHasNI n banks))

bankHasNI :: NI -> Bank -> Bool
bankHasNI n bank = any (\person -> ni person == n) bank
要求阅读:


把它分成更小的问题。此外,使用高阶函数代替手动递归,使算法更易于理解:

inBank :: NI -> Bank -> Bool
ni `inBank` bank = any (\(ni', _, _) -> ni' == ni) bank

inMarket :: NI -> Market -> Bool
ni `inMarket` market = any (ni `inBank`) market

bankless :: Pop -> Market -> Pop
bankless pop market = filter (not . (`inMarket` market)) pop
如果您进行测试,您会得到:

>>> bankless sco [rbs, clyde]
[11,12,13,15,16,18]

我想这是家庭作业,所以只为你解决问题是不好的,但这里有一些提示:

这有助于将您的职能作为一个问题正式化:考虑到这一人群和这些银行客户名单,他们中谁没有账户? 鉴于上述问题公式,将无银行功能视为过滤器是很自然的。这里有一些人,对于每个人来说,只有在没有银行账户的情况下才保留它。 过滤列表可以用很多不同的方法实现,对于初学者来说,最简单的方法可能是使用列表理解:

bankFree :: Pop -> Market -> Pop
bankFree pop market = [p | p <- pop, not (isBankCustomer market p)]

您想在这里做的是以某种方式检查ni是否出现在任何银行的客户名单中。

顺便问一下,是国家保险号码吗?@pigworker在这种情况下,它们是Int的,因此ni=1,NI=2,依此类推。@pigworker:至少根据尼尔和他发出的作业来看。就作业而言,它们可能是数字,所以尼尔的选择是完全合理的。你已经举手了。@pigworker:是的,我对它们是Int没有问题,它使搜索数字比搜索整个字符串更容易一些,我知道你在说什么,我没有读过你之前的帖子,但是在检查了我的代码后,我成功地整理了我的代码,让它完成了我想要的。谢谢你的帮助。我知道bankFree应该为那些没有账户的人过滤市场,但是在使用它的过程中,我发现自己被太多的代码困住了,以至于我不知道自己在做什么。后来我意识到我必须研究高阶函数和列表理解,以便更好地理解haskell,让我的生活更轻松。
>>> bankless sco [rbs, clyde]
[11,12,13,15,16,18]
bankFree :: Pop -> Market -> Pop
bankFree pop market = [p | p <- pop, not (isBankCustomer market p)]
isBankCustomer :: NI -> Market -> Bool   
isBankCustomer ni market = ?