2010-05-08 82 views
6

這不是一個實際的重要問題,但我希望在F#中看到一個tacit programming的例子,其中我的函數可以有多個參數(不是以列表或元組的形式) 。使用F的默認編程風格#

其次,這些功能如何操縱複雜數據結構。我正在F#Interactive上試用它,但還沒有成功。

我試過,例如:

> (fun _ -> (fun _ -> (+))) 333 222 111 555 

是不是正確的方式?

和:

> (fun _ -> (fun _ -> (+))) "a" "b" "c" "d";; 

val it : string = "cd" 
+3

你應該使用「無點」而不是「無意義」。這是標準術語。 :) – 2010-06-04 03:19:04

回答

4

F#不包含一些在哈斯克爾(主要是因爲F#程序員通常更喜歡編程的明確的風格,只在最明顯的情況下,使用pointfree風格中提供的基本功能,它不會影響可讀性)。

但是你可以定義這樣幾個基本的組合子:

// turns curried function into non-curried function and back 
let curry f (a, b) = f a b 
let uncurry f a b = f (a, b) 

// applies the function to the first/second element of a tuple 
let first f (a, b) = (f a, b) 
let second f (a, b) = (a, f b) 

現在,您可以實現添加使用組合算符兩個字符串的長度的功能如下:

let addLengths = 
    uncurry (((first String.length) >> (second String.length)) >> (curry (+))) 

這種構造兩個功能將String.length應用於元組的第一個/第二個元素,然後進行組合,然後使用+添加元組的元素。整個東西被包裝在uncurry中,所以你得到string -> string -> int類型的功能。

+0

我檢查了在FSI,它確實工作!非常感謝你;順便說一句,你能解釋你是如何得到這個元組函數組合語法的?我的意思是'(第一個String.length)>>(第二個String.length)'這對我來說看起來有些不尋常;) – Bubba88 2010-05-08 17:53:44

+0

這是用函數組合'>>'實現的。例如'f >> g'表示對於參數'x',它將調用'g(f(x))'。在上面的例子中,第一個函數('first String.length')將一個元組「string * string」變成一個元組「int * string」,而第二個函數('second String.length')將其變成'int * int'包含長度。 – 2010-05-08 18:02:24

+0

你實際上正在爲F#實施箭頭;)好吧,爲什麼不 - 箭發明是作爲monads和默認編程的組合發明的。 – Dario 2010-08-10 15:30:08

2

在F#中,函數的參數數量是固定的,所以你不會是能寫

(op) 1 2 

(op) 1 2 3 4 

對於任何給定的運營商都op。如果這是您想要的,您將需要使用列表或其他數據結構。如果你只是想避免命名變量,你總是可以做「1 + 2 + 3 + 4」。在F#中添加數字列表的最常用的方式是List.sum [1;2;3;4],這也避免了變量。