2012-05-09 51 views
4

我將基於OCaml中,以F#的幾個模塊,跑進像這樣將OCaml轉換爲F#:F#可以將值列表直接映射到標識符列表嗎?

let [x; y; z] = map func1 ["a"; "b"; "c"] 

其中[x; y; z]是標識符和 map func1 ["a"; "b"; "c"]回報的功能列表的列表。

目前我列表中的每個值綁定到所述標識符分別即

let fList = map func1 ["a"; "b"; "c"] 
let x = fList.[0] 
let y = fList.[1] 
let z = fList.[2] 

使用該標識符是用於第二功能即

func2 x y z 

我知道可以修改FUNC2到接受一個列表,但是因爲func2實際上爲每個參數都帶有每個函數的值,所以它會更加有效。即

func2 (x g) (y h) (z i) 

我已經找到了像OCaml一樣高效地完成這項任務的方法,並且空着。 我搜索了unmap,解構和查看方法List

Can F#可以將值列表直接映射到標識符列表嗎?

編輯

我不轉換定義自己的庫映射函數的代碼。

編輯

@OnorioCatenacci這只是一些我寫的一個例子,而不是試圖花多少分鐘創造一個真正的工作示例。真正的代碼有版權,所以我不能在沒有完全披露的情況下使用它。我試圖做的一點是,我沒有爲標識符分配常量值,而是爲標識符賦值。我只是在map func1 ["a"; "b"; "c"]中顯示函數是根據需要根據某些輸入生成的,而不是硬編碼的。真正的代碼構建邏輯電路仿真器,返回的功能是不同的邏輯電路;想想combinators。它是自動定理證明器的一部分。托馬斯和丹尼爾明白這個問題,並給出了正確的答案,我用真實的代碼進行了驗證。

換句話說,func1 "a"將使用參數"a"返回一個函數。 map func1 ['a", "b", "c"]將返回一個函數列表。由於F#中的函數爲first-class,因此可以將它們作爲值返回。

+0

嗨蓋伊 - 只是好奇的東西。你能否放大你關於'map func1 [「a」;「b」;「c」]返回一個函數列表的問題部分。那個調用不會返回一個列表 - 一個簡單的列表而不是函數列表?你能爲我解釋一點嗎?我的意思是我只是不太關注你,我想了解你在說什麼。 –

+0

@OnorioCatenacci請參閱編輯。 –

+0

感謝您的進一步解釋。我知道我必須錯過一些東西。 –

回答

7

您可以將映射應用於列表,然後使用模式匹配將元素綁定到F#中的標識符。語法是完全一樣的,你寫的樣品中:

let [x; y; z] = List.map func1 ["a"; "b"; "c"] 

這個例子唯一的問題是,F#編譯器不能靜態地驗證結果將是長度爲3的列表,所以它給你一個警告說「此表達式中的模式匹配不完整」。在這個例子中,它實際上並不會發生,但是如果您錯誤地重新定義了map,以至於它會丟棄第一個元素,那麼代碼將會中斷。

這只是一個警告,所以你可以忽略它,但如果你想避免它,你將需要使用match並拋出一些自定義異常在意料之外的情況:

match List.map func1 ["a"; "b"; "c"] with 
| [x; y; z] -> 
    // Continue here if the pattern matching does not fail 
    func2 (x g) (y h) (z i) 
| _ -> invalidOp "Pattern matching failed" 
+0

工作正常。 :) –

+0

很好的模式匹配擴展答案,這也工作。 :) –

+0

相同的警告發生在OCaml – newacct

6

如果您要避免「不完整的模式匹配」警告托馬斯提到,您可以使用元組 - 這都有固定的長度 - 和定義自己的map功能:

module Tuple3 = 
    let map f (a, b, c) = (f a, f b, f c) 

let x, y, z = Tuple3.map func1 ("a", "b", "c") 
+0

工作。 :) –