文字列のすべての順列のセットを生成する関数を作成しています。"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)
では、これはどのように矛盾しているのでしょうか。