簡體   English   中英

Haskell根據給定的輸入創建一個n元組

[英]Haskell create an n-ary tuple from given input

說實話,我對Haskell很新,試圖解決問題(編程練習)我過來了。 它說我應該創建一個函數

com :: Int -> [t] -> [[t]]

返回n個元素的所有可能選擇,其中n和list分別是第一個和第二個參數。 可以以不同的順序再次拾取元素。 結果如下:

com 2 [1,2,3] = [[1,1], [1,2]..[3,3]]

對於n = 1和n = 2的情況,我設法解決了這些情況。 情況n = 1非常簡單,對於n = 2的情況,我會使用連接並構建它。 但是,我不明白它是如何成為n-ary並為所有人工作的。 就像突然一個函數調用就像com 10 ...

這是你想要的嗎?

> sequence (replicate 3 "abc")
["aaa","aab","aac","aba","abb","abc","aca","acb","acc"
,"baa","bab","bac","bba","bbb","bbc","bca","bcb","bcc"
,"caa","cab","cac","cba","cbb","cbc","cca","ccb","ccc"]

上面利用了list monad中的sequence構建列表列表的笛卡爾積的事實。 所以,我們可以簡單地復制我們的列表n次,然后拿出產品。

(注意上面的"abc"是charatcters列表的簡寫['a','b','c']

所以,解決方案可能是

com n xs = sequence (replicate n xs)

或等效地,正如Daniel Wagner在下面指出的,

com = replicateM

最后一點:我確實意識到這對於實際學習如何編程可能沒什么幫助。 實際上,我從庫中提取了兩個“神奇”功能來解決任務。 不過,它顯示了如何將問題簡化為兩個子問題:1)復制n次值和2)構建笛卡爾積。 如果您不想使用該庫,第二項任務本身就是一項很好的練習。 您可能希望從以下開始解決:

sequence :: [[a]] -> [[a]]
sequence []     = [[]]
sequence (x:xs) = ...
       where ys = sequence xs

首先: []是一個列表構造函數,而不是元組。 我不知道構建n元組的任何一般方法。

但是,堅持列表,如果你有n = 1案例解決和n = 2案件解決,嘗試用前者表示后者。 然后根據n-1推廣到任何n

com n xs = concat [map (x:) (com (n-1) xs) | x <- xs ]

編寫它的一種更冗長的方式,但在嘗試理解List非確定性並試圖准確理解Haskell理解語法糖的真正含義時,可能更有用的是使用do notation編寫:

com :: Int -> [a] -> [[a]]
com 0 _  = []
com 1 xs = [[x] | x <- xs]
com n xs = do
    x <- xs
    let ys = com (n - 1) xs
    map (x:) ys

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM