4

Haskellは美しいです。あれは事実です。それは簡潔で速いなどです。あなたの多くはそれを書くことは大きな喜びであることを認めるでしょう。一方で、あまりにも洗練されたコードを書き込もうとすると、その簡潔さが不利になるかもしれないと思います。たとえば、最近友人のプロジェクトを開いて、次のようなものを見つけました。

stationDepartures id sc=map (\(s1,list)->(stationName $ (stationMap $ system sc) Map.! s1,list)) ( Map.toList (Map.fromListWith (++) (map (\((s1,s2),(d,start,dur))->(s2,[start])) (Map.toList (Map.filterWithKey (\(s1,s2) _ ->s1==id) (Map.unions (List.map times (Map.elems $ schedule sc))))))))

このワンライナーは私には絶対に読めませんでした。これはもちろん非常に極端な例ですが、私のHaskellコードが他の人には読めないように見えるかもしれないことに気付くのに役立ちました。Haskellで美しいコードを作成するための原則は何だろうと思い始めました。たとえば、ラムダ関数はコードを読みにくくするため、不要であると見なされる人もいます。あれについてどう思う?Haskellコードが「美しい」と見なされるために満たすべき要件は何ですか?

4

1 に答える 1

20

「このワンライナーをもっと読みやすい形で書くにはどうすればいいですか?」とあなたが尋ねたと思います。そうでなければ、質問は少し主観的すぎます。

ワンライナーはどの言語でも問題がありますが、Haskellは、二項演算子(優先順位規則付き)、高階関数(名前を付けるのが難しい)、および(gasp!)高階関数が豊富であるために特に問題になる可能性があります。二項演算子。ただし、ワンライナーではほとんどの括弧を削除できることに注意することから始めることができ、式が一緒に構成された一連の関数であることを示すことができます。各関数は別々の行に記述し、で構成することができます。.最後$に、すべてを引数に適用します。

stationDepartures id sc =
  map (\(s1,list) -> (stationName $ (stationMap $ system sc) Map.! s1,
                      list)) .
  Map.toList .
  Map.fromListWith (++) .
  map (\((s1,s2),(d,start,dur)) -> (s2,[start])) .
  Map.toList .
  Map.filterWithKey (\(s1,s2) _ -> s1 == id) .
  Map.unions .
  List.map times .
  Map.elems $ schedule sc

私にとって、これはかなり読みやすいです。なぜなら、そこにあるパターンを認識し、データの流れを下から上にたどることができるからです。(注:これが、すべてのMap関数が最初のパラメーターではなく最後のMapパラメーターとしてを使用する理由です。HaskellAPIを設計するときは、これを覚えておいてください!)

たとえば、Map.toList . Map.fromListWith fパターンは非常に一般的であり、ワンライナーでそれを見るのは難しいです(少なくとも私の目には)。コードはそれほど洗練されたものではなく、改行が外科的に削除されただけです。

しかし、読みやすさは主観的です。

読みやすいスタイルを開発します。言語を理解するにつれて、スタイルが進化し、「美しいコード」の感覚が進化します。ただそれを起こさせて、あなたがもう楽しくない書き直しであまり行き詰まらないようにしてください。

于 2012-06-20T22:22:54.260 に答える