2012-02-22 7 views
4

私はHaskellを学んでいます。これは構文を理解するための最初のステップです。私は非常に苦労しています。残念ながら、言語リファレンスは役に立ちません。printfから返されるものは何ですか?

私は:type (line_length 1 2 3 4)をしようとしましたが、私は赤色を持っていますreference on printfしかし、それは単語の代わりに曖昧な意味を持つシンボルを使用します。だから、私は立ち往生して助けを求めている。

シンプルに:???の代わりに何を書いてください。

line_length :: Integer -> Integer -> Integer -> Integer -> ??? 
line_length ax ay bx by = 
      printf ("The length of the line between the points" ++ 
      "(%d,%d) and (%d,%d) is %.5f\n") ax ay bx by 
      ((((fromIntegral (ax - bx)) ** 2.0) + 
      ((fromIntegral (ay - by))) ** 2.0) ** 0.5) 
+6

ハスケルを学びたいなら、Printfは良いスタートではありません。 'line_length'が返すタイプは何ですか? – augustss

+2

BTW、 '(^ 2)'は '(** 2)'よりも優れており、 'sqrt'は'(** 0.5) 'よりも優れています。 – augustss

+1

言語リファレンスは、構文を理解しようとすると、非常に良い学習ソースではありません。 [LYAH](http://learnyouahaskell.com/)、[RWH](http://book.realworldhaskell.org/)、[YAHT](http://www.realhorldhaskell.org/)のような簡単な本/チュートリアルの1つを試してみましたか? //www.cs.utah.edu/~hal/htut/)? – leftaroundabout

答えて

12

オーバーロードされた戻りタイプprintf :: PrintfType r => String -> rは少し混乱させる可能性がありますが利用可能なPrintfTypeインスタンスを見て:

  1. まず、私たちは、このインスタンスを持っている:

    instance (PrintfArg a, PrintfType r) => PrintfType (a -> r) 
    

    この1はprintfは、可変個の引数を取ることを可能にするために使用されます。これはカリングのため意味をなさないでしょうが、関数の "本当の"戻り値の型とは思わないでしょう。この方法の詳細については、How does printf work in Haskell?を参照してください。

  2. はその後、我々は、これは我々がIOアクションとしてそれを使用することができることを意味し

    instance PrintfType (IO a) 
    

    、このインスタンスを持っています。 printと同様に、これは結果を標準出力に出力します。アクションの結果はundefinedなので、無視してください。

    > printf "Foo %d\n" 42 :: IO() 
    Foo 42 
    > it 
    *** Exception: Prelude.undefined 
    
  3. そして最後に、ここに

    instance IsChar c => PrintfType [c] 
    

    型クラスは、これはHaskellの98に準拠することができるように、ほとんどです。 IsCharの唯一のインスタンスがCharあるので、あなたは

    instance PrintfType String 
    

    と考えることができますが、それはGHC特有の拡張FlexibleInstancesを必要とします。

    このインスタンスが意味することは、Stringを印刷せずに返すこともできます。これは、Cのsprintfに似ています。

    > printf "Foo %d\n" 42 :: String 
    "Foo 42\n" 
    

ですから、結果を印刷したり、それを返すようにしたいかに応じて、あなたはあなたの例ではIO()またはStringのいずれかで???を置き換えることができます。

しかし、そこにあなたがする最後の引数を望んでいた入力コンパイラが決定することができないという点で、あなたのコードを持つ別の問題があるので、あなたは、型注釈でそれを手助けする必要があります。

line_length :: Integer -> Integer -> Integer -> Integer -> String 
line_length ax ay bx by = 
      printf ("The length of the line between the points" ++ 
      "(%d,%d) and (%d,%d) is %.5f\n") ax ay bx by 
      ((((fromIntegral (ax - bx)) ** 2.0) + 
      ((fromIntegral (ay - by))) ** 2.0) ** 0.5 :: Double) 

これは拡張を避けるために行われます。拡張子を使用すると、instance PrintfType (IO())と書くことができ、結果は()になります。

1

私がタイプシグネチャで立ち往生するとき、私はハスケルが私のために大変な仕事をするようにしました。それは私

  • はそれが対話的Haskellは署名ダウン(必ずそれがどのような私だ​​作ること
  • コピーをそれを与えた型をチェックghci
  • 負荷型シグネチャなしで定義を書き、あります意図したもの)
+5

この場合、それはむしろ情報価値がないでしょう。 – augustss

関連する問題