我正在寫一個函數來產生一組字符串的所有排列 - 「foo」應該返回{「foo」,「ofo」,「oof」}。我已經在Clojure中完成了這項工作,所以我知道這種方法是正確的,但我想我會在Haskell中練習。以下是我所擁有的。爲什麼這不是很好打字?
import qualified Data.Set as Set
substr :: String -> Int -> Int -> String
substr s start end = take (end - start) . drop start $ s
substrs :: String -> Set.Set (Char, String)
substrs s = let len = length s
in foldl (\acc x -> Set.insert (s !! x, ((substr s 0 x)++(substr s (succ x) len))) acc) Set.empty [0..len-1]
-- not sure about the type
permute [] = Set.empty
permute s = Set.map recurFunc (substrs s)
where recurFunc (c, s) = Set.map (c:) (permute s)
main :: IO()
main = print $ permute "foo!"
這當然不會編譯,或者我不會問。我得到:
permute.hs:12:21:
Couldn't match expected type `String'
with actual type `Set.Set [Char]'
Expected type: (Char, String) -> String
Actual type: (Char, String) -> Set.Set [Char]
In the first argument of `Set.map', namely `recurFunc'
In the expression: Set.map recurFunc (substrs s)
Set.map
被聲明爲(a -> b) -> Set a -> Set b
。據我所知,recurFunc
需要一組(Char, String)
對,並返回一組字符串。 substrs
返回一組(Char, String)
對。那麼這是如何不一致?
我建議先開始使用基於列表的版本,然後調整它以便稍後使用「設置」,如果您決定真的需要它。列表不那麼令人困惑(並且無論如何,對於像這樣的少量數據來說'Set'並不是一個更快的事情)。 – 2013-04-10 03:41:52