2016-09-22 14 views
4

これは非常に基本的なことですが、私は関数型プログラミングとF#を初めて使用しています。リスト内の各タプルに関数を適用する

私は基本的に私はpairList内の各タプルにいくつかの機能を適用したい

をタプルのリストを取る関数(文字列* 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) 
上記 aFunctionは、あなたもそれのために特別な機能を望まないかもしれないので、簡単です

// 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 

注:

3

そして、ここでは、ジョンはに触れたList.mapオプションです、それはあなたにどこでもフルでList.map convertTuple myListを入力し、おそらくより直感的ですそれが必要。

これはF#の一般的な考えです。作成したい最小限の変換であるヘルパーから始め、次にコンビネータを使用してより大きなものにそれらを構築します。

関連する問題