5
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

PureScriptのガード節とwhere

Last updated at Posted at 2018-10-21

ご存知の通り(?)、PureScriptはHaskell風の構文を持ったAltJSです。しかし、あくまでHaskell「風」であるため、パッと見た限りでは全く同じに見える構文でも実際に書いてみると思わぬ違いに遭遇することがあります。

ガード節とwhereの組み合わせ

たとえばHaskellで書かれたこんなコードがあります。 (Wandboxで実行)  
若干わざとらしいコードですが、ガード節にまたがるwhereで定義した変数を見て、ガード節を使ってその値によって分岐をしています。


compareWith10 :: Int -> String
compareWith10 n
    | c == LT   = show n <> "は10より小さいです。"
    | c == EQ   = show n <> "は10です。"
    | c == GT   = show n <> "は10より大きいです。"
    | otherwise = "ありえないです。"
  where
    c = n `compare` 10

PureScriptでもそのまま動きそうなコードに見えます。しかし、実際に実行してみると・・・(Try PureScript!で実行

こんなエラーが出ます。

Unknown value c

そうなんです。PureScriptでは、whereで定義した変数はガード節をまたぐことはできないのです。

PureScriptでのwhereのスコープ

whereで定義した変数がガード節をまたぐことができない一方で、PureScriptでは個々のガード節にwhereを書けます。 (Try PureScript!で実行


compareWith10 :: Int -> String
compareWith10 n
  | n `compare` 10 == LT = show n <> s where s = "は10より小さいです。"
  | n `compare` 10 == EQ = show n <> s where s = "は10です。"
  | n `compare` 10 == GT = show n <> s where s = "は10より大きいです。"
  | otherwise            = show s      where s = "ありえないです。"

Haskellではこのコードはコンパイルできません。 (Wandboxで実行

Issue

この「whereで定義した変数がガード節をまたげない」という問題、GitHubにissueが無いか探してみたら、3年以上前からありました。

Move where clauses under guards · Issue #888 · purescript/purescript

個人的にとても不便なので、このまま放置され続けるようなら最悪自分で直せないかと考えながらPureScriptコンパイラのソースを読んだりしています。

5
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
5
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?