2016-09-22 112 views
4

對不起,如果這很基本,我是功能編程和F#的新手。將函數應用於列表中的每個元組

我不得不所以基本上我想一些功能適用於成對列表,每個元組創建一個函數,元組的列表(字符串* int)和返回元組的列表(字符串* INT)

和返回元組列表。

我猜我可以通過一個遞歸函數做到這一點。

我有下面的代碼至今:

let rec aFunction (pairList:List<string*int>): List<string*int> = 
    match pairList with 
    | [] -> [] 
    | head :: tail -> [fst head,snd (someFunc1 (someFunc2 (fst head,snd head)))] 

這基本上只是應用的各種功能只對列表的頭部,並返回我的元組的列表。

爲了得到它的工作對整個列表我試過如下:

| head :: tail -> [fst head,snd (someFunc1 (someFunc2 (fst head,snd head)));aFunction tail] 

,但我得到了以下錯誤:

這表達預計將有字符串類型* INT但這裏有類型列表<字符串* int>的

回答

4

這個函數其實已經存在 - 它被稱爲List.map

要分析你的錯誤,當你做[a;b]ab需要有相同的類型。

你想要什麼是使用連接運算符::這樣的:

| head :: tail -> (fst head,snd (someFunc1 (someFunc2 (fst head,snd head)))) :: (aFunction tail) 

但實際上你可以讓這個整潔的模式以更好的方式匹配

| (a,b) :: tail -> (a,snd (someFunc1 (someFunc2 (a,b)))) :: (aFunction tail) 
4

約翰·帕爾默回答是更不是不夠好,但我想大概也是一路過關斬將,並做有關的清晰度和可讀性如下:

let someFunc1 = id //just to make it compile 
let someFunc2 = id //just to make it compile 

let someFunc3 = someFunc2 >> someFunc1 >> snd 
let someFunc4 head = fst head, someFunc3 head 

let rec aFunction (pairList:List<string*int>): List<string*int> = 
    match pairList with 
    | [] -> [] 
    | head :: tail -> someFunc4 head :: (aFunction tail) 
3

而這裏的List.map選項約翰提到:

// make a helper function that converts a single tuple 
let convertTuple (s, i) = 
    let i1 = (s, i) |> someFunc2 |> someFunc1 |> snd // pipeline operator helps remove parens 
    s, i1 

// now you can simply 
let aFunction pairList = List.map convertTuple pairList 

// or even more simply using pointfree syntax: 
let aFunction = List.map convertTuple 

注意上述aFunction是如此簡單,你甚至可能不會想要一個特殊的功能,爲它:它也許更直觀剛打出來的全List.map convertTuple myList隨處可見需要它。

這是F#的一般想法;從一些幫助者開始,這些幫助者是你想做的最小變換,然後使用組合器將它們構建成更大的東西。

相關問題