1

トラブルシューティングが難しい場合を除いて、私はこの新しい言語を楽しんでいます。

これが私の教授が望んでいることです。彼は私にユーザーからの数値を受け入れて、実行中の平均を計算することを望んでいます。

これまでのところ、これは私の基本的なプログラムが何らかのタイプエラーに対してエラーを出すことを除いて私が持っているものです。

私はCompSciの学生です。これは、私が自分でやろうとしている課題の質問です。

   module Main (listM, main) where

   import System.IO  
   import Data.List

   listM = [1, 2, 3]


    main = do

     average listM = realToFrac (sum listM) / genericLength listM   

     putStrLn (show(listM))

今、私はこのエラーが発生し、私を夢中にさせています...:S Q1.hs:12:18:入力`='の解析エラー

4

2 に答える 2

3

Haskellの学習を楽しんでいると聞いてうれしいです!

あなたの任務に関する限り、あなたはまったく悪いことをしていません。私は言うだろう:あなたはほとんどそこにいます。

Dwilsonが彼の優れた回答で説明したように、コンパイラがプログラムを拒否する理由は、の定義がlistMインポートの前に置かれたためです。Haskellモジュールでは、常にモジュールヘッダー(プラグマが前に付く場合もあります)とインポートのリスト、そして関数の定義から始めます。

module Main (main) where

import System.IO
import Data.List

...

ここで、コンパイラ(またはおそらくインタプリタ)が「タイプエラー」のためにプログラムを拒否するとおっしゃいました。しかし、実際には「解析エラー」が発生します。2つの違いを理解することは害にはなりません。

  • コンパイラがプログラムを処理するとき、最初にプログラムが構文的に正しいかどうかをチェックします。そうでない場合は、解析エラーが発生します。

  • 次に、関数を一貫した問題で使用しているかどうかをチェックします。つまり、タイプが正しいかどうかをチェックします。そうでない場合は、タイプエラーが発生します。

一般に、最初のクラスのエラーは簡単に処理されます。コンパイラは、ほとんどの場合、間違いやタイプミス(この場合は最初のインポートステートメント)があった場合に、プログラム内のその場所を指し示します。2番目のクラスのエラーは、対処が難しい場合がありますが、優れたHaskellプログラマーになるには、型システムに精通し、そこで何が起こっているのかを実際に理解する必要があります(多かれ少なかれ機能するまで試してみるのではなく...)でも心配はいりません。思ったほど難しくはありません。

それをあなたのコードで見ると、あなたが定義していることが私を襲います

average xs = realToFrac (sum listM) / genericLength listM

つまり、引数を取る関数averageとして定義しますが、定義の右側では使用していません。あなたが平均を計算しているリストであるはずですか?コードでは、引数としてどのリストを指定しても、関数は常に修正リストの平均を計算します。それを除けば、あなたの機能は大丈夫です。xsxsxslistMaverage

今、あなたがしなければならない唯一のことは、ユーザーに入力を促す方法と、その入力から数字のリストを作成する方法についてです。

頑張って楽しんでね!;)

于 2012-07-12T09:25:46.267 に答える
2

入力エラーに関する限り、それはのimport System.IO前にインデントされているためですimport Data.List。Haskellではインデントが重要ですが、必要に応じて中括弧とセミコロンを使用できます。前の行よりも遠くにインデントされた行は、その行の継続としてカウントされるため、ghcはファイルを。として解釈しますlistM = [1, 2, 3] import System.IO

さて、それがあなたが助けを必要とした唯一のものであるなら、Haskellを楽しんでください!ただし、構造についてサポートが必要な場合は、探しているものを明確にする必要があります。あなたは教授が望んでいることとあなたが起こると期待していることの説明が一致していません。具体的には、教授はユーザーから数字を取得する必要があると言います。これは通常、コマンドラインで数字を求めることを意味しますがlistM、ユーザーから入力されていない数字をプログラムで合計する必要があると言います。どちらですか?

更新を編集
して、現在のステータスを反映しますparse error on '='

GHCのエラーは最初は気が遠くなるかもしれませんが、慣れると他の言語よりも実際にはるかに役立つことがわかりました。そこに着くのを心配しないでください!= さて、このエラーがあなたに伝えているのは、GHCが回線にヒットしたときに何をすべきかわからないということですaverage listM = realToFrac (sum listM) / genericLength listMmain = doこれは、それが行の続きとして扱われているためであり、doブロック内では、次のように、すべてのバインドをステートメントで=行う必要があります。これはおそらくあなたが望むものではありません。なぜなら、あなたの関数はdoブロックでのみ利用可能になるからです!あなたがすべきことは、ブロックの外側を定義し、それをブロックの内側のある時点で呼び出すことです。letlet average listM = realToFrac (sum listM) / genericLength listMaverageaveragedodo

いくつかのポインタ:

  • インデントは非常に重要です。Haskellは、インデントによってスコープや行末などを決定します。
  • ParseErrorsは通常、コードに構文上の問題があることを意味します。インデントに遭遇したときに最初にすべきことは、インデントをチェックしてから、かっこや角かっこなどが欠落していないかどうかをチェックすることです。
  • doブロックの場合:
    • letモナディックではない=ものをバインドするために使用されます。let x = length "foobar"
    • <-演算子は、単調なものをバインドするために使用されます。x <- getChar
于 2012-07-12T02:30:30.030 に答える