5

問題は何をするかではなくIO、それがどのように定義されているか、その署名です。具体的には、これはデータかクラスか、aその型パラメーターは " " か? どこにも見つかりませんでした。また、私はこれの構文上の意味を理解していません:

f :: IO a
4

6 に答える 6

12

がデータ型であるかどうかを尋ねIO aました。そうです。そして、がその型パラメーターであるかどうかを尋ねaました。そうです。あなたはその定義が見つからないと言いました。それを見つける方法をお見せしましょう:

localhost:~ gareth.rowlands$ ghci
GHCi, version 7.6.3: http://www.haskell.org/ghc/  :? for help
Prelude> :i IO
newtype IO a
  = GHC.Types.IO (GHC.Prim.State# GHC.Prim.RealWorld
                  -> (# GHC.Prim.State# GHC.Prim.RealWorld, a #))
    -- Defined in `GHC.Types'
instance Monad IO -- Defined in `GHC.Base'
instance Functor IO -- Defined in `GHC.Base'
Prelude> 

ghci では、:iまたは:info型について説明します。型宣言とそれが定義されている場所を示しています。IOそれが aMonadであり、 a であることがわかりFunctorます。

この手法は、通常の Haskell 型でより便利です。他の人が指摘しているように、IOHaskell では魔法です。典型的な Haskell 型では、型シグネチャは非常に明確ですが、知っておくべき重要なことIOはその型宣言ではなく、IOアクションが実際に実行されることIOです。これは、通常は基盤となる C または OS ルーチンを呼び出すことによって、かなり従来の方法で行われます。たとえば、Haskell のputCharアクションは C のputchar関数を呼び出す場合があります。

于 2013-08-18T06:33:37.797 に答える
1

あなたが私に尋ねるなら、これはとても良い質問です。私もこれについて非常に混乱したことを覚えています、多分これは助けになるでしょう...

'IO' は型コンストラクター、'IO a' は型、'a' ('IO a' 内) は型変数です。文字「a」には意味がありません。文字「b」または「t1」も同様に使用できます。

IO 型コンストラクターの定義を見ると、次のように定義された新しい型であることがわかります: GHC.Types.IO (GHC.Prim.State# GHC.Prim.RealWorld -> (# GHC.Prim.State# GHC .Prim.RealWorld、a #))

'f :: IO a' は 'f' と呼ばれる関数の型であり、明らかに引数がなく、IO モナドの制約のない型の結果を返します。'in the IO monad' は、結果の計算中に f が何らかの IO を実行できることを意味します (つまり、'RealWorld' を変更します。'change' は、提供された RealWorld を新しいものに置き換えることを意味します)。f の結果は多態的です (これは、'Int' のような型定数ではなく、型変数 'a' です)。ポリモーフィックな結果とは、プログラム内で結果の型を決定するのは呼び出し元であることを意味します。したがって、ある場所では f を使用すると Int が返され、別の場所では String が返される可能性があります。「制約なし」とは、返すことができる型を制限する型クラスがないため、任意の型を返すことができることを意味します。

パラメータがなく、Haskell は純粋なので、なぜ 'f' は関数で定数ではないのですか? IO の定義は、'f :: IO a' は 'f :: GHC.Prim.State# GHC.Prim.RealWorld -> (# GHC.Prim.State# GHC.Prim.RealWorld, a #)' など、実際にはパラメータがあります。「現実世界の状態」です。

于 2013-08-19T13:10:05.110 に答える
0

データ内のIO a aは、主に と同じ意味を持ちMaybe aます。しかし、次のようにコンストラクターを取り除くことはできません。

fromIO :: IO a -> a
fromIO (IO a) = a

幸いなことに、次のように、このデータをモナドで使用できます。

{-# LANGUAGE ScopedTypeVariables #-}
foo = do
   (fromIO :: a) <- (dataIO :: IO a)
    ...
于 2013-08-18T14:26:42.723 に答える