152

ghciで複数行のコマンドを入力する際に​​問題が発生しました。

次の2行のコードはファイルから機能します。

addTwo :: Int -> Int -> Int
addTwo x y = x + y

しかし、ghciに入ると、エラーが発生します。

<interactive>:1:1: error:
    Variable not in scope: addTwo :: Int -> Int -> Int

また、コードを中に入れてみました:{ ... :}が、この例では機能していません。これは、行を1行に追加しているだけなので、そうではないはずです。

WinGHCiバージョン2011.2.0.1を使用しています

4

5 に答える 5

201

ほとんどの場合、型推論を利用して署名を作成できます。あなたの例では、以下で十分です。

Prelude> let addTwo x y = x + y

型アノテーションを使用した定義が本当に必要な場合、または定義が複数行にまたがる場合は、ghciでこれを行うことができます。

Prelude> :{
Prelude| let addTwo :: Int -> Int -> Int
Prelude|     addTwo x y = x + y 
Prelude| :}
Prelude> addTwo 4 7
11

これを1行に絞ることもできることに注意してください。

Prelude> let addTwo :: Int -> Int -> Int ; addTwo x y = x + y

ドキュメントのプロンプトセクションで、インタラクティブ評価でghciとの対話について詳しく知ることができます。

于 2011-12-09T08:52:34.547 に答える
137

GHCIを起動して次のように入力することで、この問題を解決します:set +m

Prelude> :set +m
Prelude> let addTwo :: Int -> Int -> Int
Prelude|     addTwo x y = x + y
Prelude| 
Prelude> addTwo 1 3
4

ブーム。


ここで起こっていること(そして私は主にあなたと話している、 Learn You A Haskellを進めている間、助けを求めてグーグルしている人)は、GHCIは関数名のバインディングをその場で変更するインタラクティブな環境であるということです。関数定義をブロックでラップする必要がありletます。そうすれば、Haskellはあなたが何かを定義しようとしていることを知ることができます。これは、複数行のコード:set +m構造の省略形です。:{ :}

空白はブロックでも重要であるため、タイプ定義の後に関数定義を4つのスペースでインデントして、の4つのスペースを考慮に入れる必要がありますlet

于 2012-11-12T09:52:39.490 に答える
15

使用let

Prelude> :{
Prelude| let addTwo :: Int -> Int -> Int
Prelude|     addTwo x y = x + y
Prelude| :}
Prelude> addTwo 2 3
5
于 2011-12-09T08:54:29.040 に答える
5

GHCIバージョン8.0.1以降、letREPLで関数を定義する必要はなくなりました。

したがって、これは問題なく機能するはずです。

λ: addTwo x y = x + y
λ: addTwo 1 2
3
λ: :t addTwo
addTwo :: Num a => a -> a -> a

Haskellの型推論は、floatでも機能する一般化された型を提供します。

λ: addTwo 2.0 1.0
3.0

独自のタイピングを提供する必要がある場合はlet、複数行入力と組み合わせて使用​​する必要があるようです(:set +mGHCIで複数行入力を有効にするために使用)。

λ: let addTwo :: Int -> Int -> Int
 |     addTwo x y = x + y
 | 
λ: addTwo 1 2
3

Intただし、非多形型のタイピングが原因以外のものを渡そうとすると、エラーが発生します。

λ: addTwo 2.0 1.0

<interactive>:34:8: error:
    • No instance for (Fractional Int) arising from the literal ‘2.0’
    • In the first argument of ‘addTwo’, namely ‘2.0’
      In the expression: addTwo 2.0 1.0
      In an equation for ‘it’: it = addTwo 2.0 1.0
于 2018-12-30T06:20:38.293 に答える
4

アーロンホールの答えを拡張するために、少なくともバージョンGHCi 8.4.4では、スタイルletを使用する場合は型宣言で使用する必要はありません。:{ :}これは、後続のすべての行に4スペースのインデントを追加して説明する必要がないことを意味します。これによりlet、長い関数の入力がはるかに簡単になり、多くの場合、コピーと貼り付けが行われます(元のソースにはない可能性が高いため)正しいインデント):

λ: :{
 | addTwo :: Int -> Int -> Int
 | addTwo x y = x + y
 | :}
λ: addTwo 1 2
3

アップデート

別の方法として、で複数行入力モードをオンにしてから、独自に入力し、Enterキーを押して、インデントを必要とせずに定義を貼り付けることができます:set +mlet

ただし、これは次のような一部のコードブロックでは機能しないようです。

class Box a where
  mkBox :: a -> Boxes.Box

しかし:{:}テクニックはそうです。

于 2020-05-12T02:24:33.337 に答える