我是f新手#用F#計算笛卡爾乘積列表的乘積
我試着計算笛卡爾乘積的列表中的乘積。我「借」這個。
let xs = [1..99]
let ys = [1..99]
seq {for x in xs do for y in ys do yield x * y}
有沒有更好或更優雅的方式?
加里
我是f新手#用F#計算笛卡爾乘積列表的乘積
我試着計算笛卡爾乘積的列表中的乘積。我「借」這個。
let xs = [1..99]
let ys = [1..99]
seq {for x in xs do for y in ys do yield x * y}
有沒有更好或更優雅的方式?
加里
另一個possibiltiy基於列表模塊提供的是功能來解決這個問題:
let xs = [1..99]
let ys = [1..99]
let zs = xs |> List.collect (fun x -> ys |> List.map (fun y -> x*y))
避免了額外要求,以.concat,也應該做的工作。
但我會堅持你的解決方案。它應該是最可讀的,它是一個真正的匹配者。 (只是試着大聲地讀出代碼,你完全可以理解,而Noldorins或我的不是)
的確有一個稍微更優雅的方式(至少在功能意義上)來計算笛卡爾乘積,其使用存在於List
類內的功能。 (有沒有必要讓序列或環這裏,至少不是直接)
試試這個:
let xs = [1..99]
let ys = [1..99]
xs |> List.map(fun x -> ys |> List.map(fun y -> x * y)) |> List.concat
稍長無可否認,儘管功能更強大的風格,它似乎。
聲明:我沒有安裝當前F#的機器,所以我無法測試我的代碼。基本上,不過,如果你從哈斯克爾偷sequence
,你可以寫你的程序作爲
let cartesian = sequence >> List.map product
,並運行它
cartesian [[1..99]; [1..99]]
下面是如何寫sequence
。這是你寫的序列表達式的一個通用版本。它只處理無限數量的列表:{ for x in xs do for y in ys do for z in zs ... yield [x;y;z;...] }
。
let rec sequence = function
| [] -> Seq.singleton []
| (l::ls) -> seq { for x in l do for xs in sequence ls do yield (x::xs) }
// also you'll need product to do the multiplication
let product = Seq.fold_left1 (*)
然後,你可以寫你的程序作爲
let cartesian xs ys = [xs; ys] |> sequence |> List.map product
// ... or one-argument, point-free style:
let cartesian' = sequence >> Seq.map product
您可能需要改變一些Seq
s到List
秒。
但是,能夠猜出非一般列表理解含義的人數可能比識別名稱sequence
多很多,所以你可能比列表理解更好。 sequence
隨時可以運行整個計算表達式列表。
相關問題在這裏:http://stackoverflow.com/questions/482866/f-cross-product-of-two-lists – Benjol 2009-06-02 06:56:56