2664


例えば、以下のような式をエラーを出さずに出力したいと思います。

  * `\x -> x ^ 4`
  * `(^4)`
  * `map (^4)`

ghci(対話環境) で試していたところ `show (\x -> x ^ 4)` では、 以下のようなエラーがでてしまいます。

[code]

    Prelude> show (\x -> x ^ 4)
    
    <interactive>:6:1:
        No instance for (Show (a0 -> a0)) arising from a use of ‘show’
        In the expression: show (\ x -> x ^ 4)
        In an equation for ‘it’: it = show (\ x -> x ^ 4)
    
    <interactive>:6:15:
        No instance for (Num a0) arising from a use of ‘^’
        The type variable ‘a0’ is ambiguous
        Relevant bindings include x :: a0 (bound at <interactive>:6:8)
        Note: there are several potential instances:
          instance Num Double -- Defined in ‘GHC.Float’
          instance Num Float -- Defined in ‘GHC.Float’
          instance Integral a => Num (GHC.Real.Ratio a)
            -- Defined in ‘GHC.Real’
          ...plus three others
        In the expression: x ^ 4
        In the first argument of ‘show’, namely ‘(\ x -> x ^ 4)’
        In the expression: show (\ x -> x ^ 4)
    
[/code]

## 追記: 2014-12-16

コメントで頂いたように、 `:type` を利用すると `ghci` では型が表示でき、良好な結果が得られます。

[code]

    Prelude> :type (\x -> x ^ 4)
    (\x -> x ^ 4) :: Num a => a -> a
    
    Prelude> :type (^4)
    (^4) :: Num a => a -> a
    
    Prelude> :type map (^4)
    map (^4) :: Num b => [b] -> [b]
    
[/code]

一方、対話環境以外でも同様の結果を得たくなります。例えば以下のようなコードです。しかし、エラーとなってしまうわけです。

[code]

    main = do
        print $ (\x -> x ^ 4)
        print $ (^4)
        print $ map (^4) [1..4]
    
[/code]

## 環境

  * GHC version 7.8.3
  * Windows 8.1

* * *

Note: 用語の間違いがあればぜひご指摘ください。


CC BY-SA 3.0
2014-12-25T11:43:07.693
2572
2015-01-24T19:10:32.727
2014-12-26T11:46:43.680
5021
5021
question
haskell
Haskell にて、無名関数(anonymous function)を表示する方法はありませんでしょうか


簡単に言うと、λ式(無名関数)を含め関数値を Haskell のコードとして `print` などを使って表示させる事は不可能です。

まず、 `show (\x -> x ^ 4)` が失敗している点。これは関数型 (`a -> b`) に対する `Show`
インスタンスが定義されていないのが理由です。関数型を持つ値をどのように表示すべきかが定義されいないので Haskell
はこの式の実行を型検査の段階で拒否します。

では関数型 (`a -> b`) に対する `Show` インスタンスをうまく定義して、関数値からその関数値を表す Haskell
コード文字列が得る事が出来るか、つまり、 `show (\x -> x ^ 4)` を評価すると `"\x -> x ^ 4"`
が得られるようにできるか、というと、これも不可能です。なぜなら Haskell
には関数値からその定義コード(もしくは定義コードに対応する代数的データ)を得る方法が無いからです。なぜそのような方法が Haskell
の言語仕様上に用意されていないから、それは Haskell
はコンパイラとして実装されるという想定でデザインされた言語だからです。そこでは、関数式は(おおざっぱに言うと)マシンコードへのポインタを利用したデータにコンパイルされるので、もはや元の定義式の字面を復元する手段がありません。

ですので…諦めてください。


CC BY-SA 3.0
2014-12-26T16:51:12.713
2656
2015-01-24T19:10:32.727
2015-01-24T19:10:32.727
898
898
2572
answer


直接の回答ではありませんが，補足的に．

単純に `show` を成功させたいのであれば， `Text.Show.Functions` というモジュールがあり，これを `import`
することでエラーは回避することができます（常に `"<function>"`がかえってきますが）．

また， `ghc` であれば [`-fwarn-missing-signatures`
オプション](https://downloads.haskell.org/~ghc/7.6.2/docs/html/users_guide/options-
sanity.html) (あるいは簡単に `-Wall`)をつけてコンパイルすることで，top-level
に定義された関数で型宣言がなされていないものについて，その旨を推論された型と共に報告してくれます．

さらに， [`ghc-mod`](http://www.mew.org/~kazu/proj/ghc-mod/en/ghc-mod.html) や
[`hdevtools`](https://github.com/bitc/hdevtools)
のような補助ツールを使うことで目的を達成できるかも知れません．


CC BY-SA 3.0
2014-12-27T02:19:24.767
2664
2014-12-27T09:04:17.283
2014-12-27T09:04:17.283
2901
2901
2572
answer