1. ホーム
  2. list

[解決済み] Haskellでコマンドラインghciでリストをソートする方法

2022-02-26 17:20:24

質問

私はHaskellの初心者です。2つのリストを取ってマージし、結合したリストを小さいものから大きいものへソートする関数を作りたいと思っています。 これは、モジュールを使用せずにコマンドラインで行われる必要があります。

これは私が現在持っているものです、私は"sortList"関数が動作するように問題があります、そして、私はこれらの3行を1つの関数に結合する方法が分かりません。

let combineList xs ys = xs++ys
let zs = combineList xs ys
let sortList (z:zs) = if (head zs) < z then (zs:z) else (z:(sortList zs))

解決方法は?

ghciの中でソート関数を定義するのは少し厄介です。一番簡単な方法は、ソート関数をファイルに書いて、それをghciに読み込ませることだと思うんだ。たとえば、quicksort の簡潔なバージョン (インプレースではありません!) を、次のようなファイルに書きます。 sort.hs (から取ったもの)。 HaskellWikiの ):

quicksort :: Ord a => [a] -> [a]
quicksort []     = []
quicksort (p:xs) = (quicksort lesser) ++ [p] ++ (quicksort greater)
    where
        lesser  = filter (< p) xs
        greater = filter (>= p) xs

を作成し、ghciにロードします。

> :l sort.hs 

どうしてもghciで関数を定義したい場合は、以下のような方法があります(from ハスケル・ユーザーズ・ガイド ):

> :{
> let { quicksort [] = []
>     ; quicksort (p:xs) = (quicksort (filter (< p) xs)) ++ [p] ++ (quicksort (filter (>= p) xs))
>     }
> :}

これが定義されると、以下のことが可能になります。

> let combineAndSort xs ys = quicksort (xs ++ ys)

すでに他の回答で説明されているように、もちろん、ソートをインポートするだけなら Data.List しかし、手動で行うのは良い訓練になることは間違いありません。

ご質問の内容から、Haskellの変数のスコープについて少し混乱されているようですね。この行では

> let combineList xs ys = xs++ys

という変数を導入します。 xsys . 等号の左側に記載するのは、単に combineList は2つの変数を取り、その関数本体では、これらの変数を xsys . 関数の外では名前を紹介しないので、次の行の

> let zs = combineList xs ys

という名前は、実際には意味を持ちません。 xsys の範囲内においてのみ有効です。 combineList . を作るには zs に値を与える必要があります。 combineList 具体的な引数、例えば..:

> let zs = combineList [2,4,6] [1,3,5]  --> [2,4,6,1,3,5]

しかし combineList はとてもシンプルなので、実はそのままやった方が簡単なんです。

> let zs = [2,4,6] ++ [1,3,5] --> [2,4,6,1,3,5]

最後の行は

> let sortList (z:zs) = if (head zs) < z then (zs:z) else (z:(sortList zs))

この行は、かなりいろいろな間違いがあるので、混乱したのではないでしょうか。ДМИТРИЙ МАЛИКОВの回答がそのほとんどに言及しているので、彼が言及した誤りを一つ一つ理解してみることをお勧めします。