import Control.Monad (mapM_)
プログラミング言語の違いは、異なるプログラミング言語が異なるというだけでなく、異なるプログラミング言語を異なる方法で使用することでもあります。たとえば、C と C++ は似たようなプログラミング言語ですが、C プログラムはメモリのいくつかの大きなブロックを割り当てる傾向がありますが、C++ プログラムはメモリのより多くの小さなブロックを割り当てる傾向があります。
つまり、あなたの C 関数は 2 つの配列を取り (そしてそれらの長さを明示的に渡す必要があります)、Haskell では代わりにリストを使用します。(Haskell プログラムが決して配列を使用しないと言っているわけではありません。C プログラムが決してリストを使用しないというのは正しくないのと同じように、C プログラムは配列を使用する傾向があり、Haskell プログラムはリストを使用する傾向があるということです。)
showSpaced :: Show a => a -> String
showSpaced x = " " ++ show x ++ " "
あなたの C 関数は を呼び出しますprintf()
。これは、出力をフォーマットして stdout に送信しますが、これらは別々に行います。 showSpaced
に渡すことができるすべての値で動作しますshow
。
union :: Ord a => [a] -> [a] -> [a]
union xs [] = xs
union [] ys = ys
union xs0@(x:xs1) ys0@(y:ys1) = case x `compare` y of
LT -> x : union xs1 ys0
GT -> y : union xs0 ys1
EQ -> y : union xs1 ys1
このunion
関数は、基礎となる要素を比較できることのみを必要とします。2 つのリストは、互いに同じタイプでなければなりません。ループの代わりに再帰を使用していること、および配列の代わりにリストを使用することで、配列インデックスを追跡する必要がないことに気付くでしょう。
それ自体に3 つの方程式を与えることによって、および式とともに、パターン マッチングを使用します。Haskell ではパターン マッチングが重要です。それを説明するチュートリアルを見つけてください。union
case
printUnion :: (Ord a, Show a) => [a] -> [a] -> IO ()
printUnion xs ys = mapM_ (putStr . showSpaced) (union xs ys)
それで、printUnion
すべてをまとめました。リスト要素はOrd
( を呼び出せるようにunion
) とShow
( を呼び出せるように) 実装する必要がshowSpaced
あるため、両方とも型シグネチャに表示されます。
C から来ているので、中間リストを作成する効率について心配するかもしれません。そうではありません: オプティマイザはすべてを 1 つのループに融合します。