2012-11-11 22 views
0

我想列出一些不屬於特定銀行的號碼。列出沒有賬戶的國家保險號碼

這裏是我的代碼

類型

 type NI = Int 
    type Age = Int 
    type Balance = Int 
    type Person = (NI, Age, Balance) 
    type Bank = [Person] 
    type Market = [Bank] 
    type Pop = [NI] 

銀行

 rbs :: Bank 
    rbs = [ (1, 73, 1000) 
     , (2, 18, -50) 
     , (3, 60, 190) 
     , (4, 26, 300) 
     , (5, 24, 456) 
     , (6, 32, 7500) 
     , (7, 41, -46) 
     , (8, 59, -850) 
     , (9, 44, 348) 
     , (10, 66, -1000) 

    clyde :: Bank 
    clyde = [(1, 73, 240) 
      , (2, 18, -70) 
      , (23, 30, 800) 
      , (14, 16, 30) 
      , (5, 24, 800) 
      , (19, 81, 750) 
      , (17, 49, 946) 
      , (20, 59, -850) 
      , (29, 24, -348) 
      , (30, 76, -100) 

    sco :: Pop 
    sco = [1..20] 

這是我的代碼,以檢查是否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 

如果我運行bankFree sco [rb s,clyde]應該顯示的是[11,12,13,15,16,18,20]但是出現的是[2..20]

我不知道我在做什麼錯,如何進行,所以任何關於此事的幫助將不勝感激

+0

那麼「國民保險號碼」的號碼是? – pigworker

+0

@pigworker在這種情況下,它們應該是Int的,所以NI = 1,NI = 2等等。 – Zantengetsu

+0

@pigworker:至少根據Neil和他發出的課程作業。 – Zantengetsu

回答

5

同樣,正如我在my answer to your earlier question中所建議的,你在這方面遇到這麼多困難的原因是,你沒有有效地將問題分解成更小件,而你並沒有幫助你自己去使用標準的實用功能來管理列表。你試圖一口咬下一塊太大的東西,這很難解決。

所以,你要打破你的問題分解成易於解決自己的,然後結合這些進入大解決大問題的子部分:

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 

必讀:

+0

是的,我可以看到你說什麼,我沒有閱讀你以前的帖子,但檢查後,我設法整理我的代碼,並得到它做我想要的。謝謝 – Zantengetsu

2

將其拆分成較小的問題。此外,使用高階函數代替人工遞歸來讓你的算法更容易理解:

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] 
2

我想這是功課,所以才解決這個問題對你來說是不正常的,但這裏有一些提示:

  • 它有助於形式化你的功能應該做的是一個問題:「考慮到這部分人羣並給予銀行客戶的這些名單,他們中的誰呢不是哈有一個帳戶?「
  • 鑑於上述問題的表述,將bankFree函數看作過濾器是很自然的。這裏有一些人,每個人,只有在沒有銀行賬戶時才保留。

過濾列表,可以在許多不同的方式來實現,最簡單的初學者可能是使用列表理解:

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

應該讀作:回所有的人流行說不是銀行客戶。爲isBankCustomer的定義應該是:

isBankCustomer :: NI -> Market -> Bool 
isBankCustomer ni market = ? 

你想在這裏做的就是以某種方式檢查是否妮存在於任何客戶的銀行名單。

+0

感謝您的幫助。我知道bankFree應該爲那些沒有賬戶的人過濾Market,但是在通過它的時候,我發現自己陷入了太多的代碼,我不知道什麼是做什麼。從那以後,我意識到我必須研究高階函數和列表理解,以便更好地理解哈斯克爾並使我的生活更輕鬆。 – Zantengetsu

相關問題