2017-07-14 6 views
4

Typed holesは、実装する方法を見つける素晴らしい方法を提供します。使用する関数を知っていれば、fooと言うだけで、foo _ _ _のようなものを書き出して、各引数にどのような型が必要かをコンパイラに伝えることができます。これにより、ドキュメントを参照する必要がなくなります。関数に入力する穴の数を決定する簡単な方法は何ですか?

実際に正しい番号のアンダースコアを実際に書き出す場合にのみ正しく動作します。現時点では、通常、これをいくつかの試行錯誤で判断していますが、Haskellの関数は常に部分的にしか適用できないため、何を目にするべきかは分かりません。

できるだけ早くこの番号を見つけるにはどのような方法が良いですか?

+0

@hnefatl私は、Haskellカテゴリのゴールデンバッジを持つ人は、 ':type'コマンドについて知っています:)しかし、質問はいくつかの関数の引数の正しい数を見つけるための速い方法です。'ghci'を開き、' foo'関数を使ってモジュールをロードし、 ':t foo'を印刷すると、' ghcid'デーモンを実行したときにアンダースコアを追加して結果を見るだけではるかに遅くなるかもしれません。 – Shersh

+9

おそらく、 'foo'の型を得るための素早い方法は' _ foo'を書いて、穴の型を見ることです。おそらくいくつかのIDEのようなヘルプが良いでしょう。 – chi

+0

私は@chiにこれにはIDE機能を使いたいと思うことに同意します。 'foo'と入力してその上にカーソルを置くと、そのタイプが表示されます。これは、fooのタイプと、 'foo'を部分的に適用するなど、あなたが望む結果のタイプについて懸命に考える必要があると思います。 'foo'ではなく' _'をタイプすると、ghciはどのような状況で 'foo'のタイプを関連性のあるものとして示唆していますか? –

答えて

1

@chiが示唆しているように、私が見いだした最も良いことは、「関数に穴を開ける」ことです。私はこれが質問に答えるかどうか分かりませんが、うまくいけば少なくともいくらか役立っています。

foldr :: Foldable t => (a -> b -> b) -> b -> t a -> b 
foldr = undefined 

いるあなたはどのように多くの引数が、それをタイプからだけで伝えることはできません。

私は「機能は常にただ部分的に適用することが可能」であなたは、このような機能を持っていることを意味推測しています特定のタイプの型チェックを行うために必要です。別に

bar :: String -> String 
bar = _1 foldr 

* Found hole: 
    _1 :: ((a0 -> b0 -> b0) -> b0 -> t0 a0 -> b0) -> String -> String 
    Where: `t0' is an ambiguous type variable 
     `b0' is an ambiguous type variable 
     `a0' is an ambiguous type variable 
* In the expression: _ 
    In the expression: _ foldr 
    In an equation for `bar': bar = _ foldr 

* Ambiguous type variable `t0' arising from a use of `foldr' 
    prevents the constraint `(Foldable t0)' from being solved. 
    Probable fix: use a type annotation to specify what `t0' should be. 
    These potential instances exist: 
    instance Foldable (Either a) -- Defined in `Data.Foldable' 
    instance Foldable Maybe -- Defined in `Data.Foldable' 
    instance Foldable ((,) a) -- Defined in `Data.Foldable' 
    ...plus one other 
    ...plus 22 instances involving out-of-scope types 
    (use -fprint-potential-instances to see them all) 

:2番目のエラーは、ここで特に有用ではない、t0が本当にこれらのタイプのいずれであっても可能性があるので型チェッカーはここで行うことができる最高はあなたにそれが受け入れる引数の最小数を伝えることです。しかし、あなたがこのような状況に遭遇した場合は、-fprint-potential-instancesが実際に役に立つかもしれません。あなたは今、あなたの頭の中で型チェックの少しを行うことができます

:一致するタイプのため

((a0 -> b0 -> b0) -> b0 -> t0 a0 -> b0 ) -> 
    <_1>    <_2> String -> String 

を、あなたは、少なくとも二つの穴を供給しなければなりません。さらに必要な場合がありますが、それはb0のインスタンス化に依存します。これらの穴に代入すると、あなたは、あなたも、あなたが同じことを行うことができ、その場合には

class C a where foo :: a 
instance C String where 
instance C a => C (Int -> a) where 

のような(私の意見では、愚かな)関数が発生する可能性がかなり簡単な問題

bar :: String -> String 
bar = foldr _1 _2 

* Found hole: _1 :: Char -> String -> String 

* Found hole: _2 :: String 

を取得します事実、型チェッカーは、可能なすべてのインスタンスを通知します:

bar :: String -> String 
bar = _ foo 

test0.hs:6:7: warning: [-Wtyped-holes] 
    * Found hole: _ :: t0 -> String -> String 
     Where: `t0' is an ambiguous type variable 
    * In the expression: _ 
     In the expression: _ foo 
     In an equation for `bar': bar = _ foo 
    * Relevant bindings include 
     bar :: String -> String (bound at test0.hs:6:1) 

test0.hs:6:9: warning: [-Wdeferred-type-errors] 
    * Ambiguous type variable `t0' arising from a use of `foo' 
     prevents the constraint `(C t0)' from being solved. 
     Probable fix: use a type annotation to specify what `t0' should be. 
     These potential instances exist: 
     instance C a => C (Int -> a) -- Defined at test0.hs:3:10 
     instance C String -- Defined at test0.hs:2:10 
    * In the first argument of `_', namely `foo' 
     In the expression: _ foo 
     In an equation for `bar': bar = _ foo 

ここで本当にgあなた。 barは1つの引数を取るので、この(確かに考案された)例では、おそらく1つの引数が必要だと思います。

bar :: String -> String 
bar = foo . _ 

test0.hs:6:7: warning: [-Wdeferred-type-errors] 
    * Ambiguous type variable `b0' arising from a use of `foo' 
     prevents the constraint `(C (b0 -> String))' from being solved. 
     (maybe you haven't applied a function to enough arguments?) 
     Probable fix: use a type annotation to specify what `b0' should be. 
     These potential instance exist: 
     instance C a => C (Int -> a) -- Defined at test0.hs:3:10 

test0.hs:6:13: warning: [-Wtyped-holes] 
    * Found hole: _ :: String -> b0 
     Where: `b0' is an ambiguous type variable 

今ではそこに一つの潜在的インスタンスであり、そしてあなたがその穴のタイプは本当にString -> Intなければならないことを推測することができますを示しています。

関連する問題