2016-11-25 14 views
4

これは、例えば関数です:明示的な型変換ですか?

import qualified Data.ByteString.Lazy as LAZ 
import qualified Data.ByteString.Lazy.Char8 as CHA 
import Network.Wreq 

makeRequest :: IO (Network.Wreq.Response LAZ.ByteString) 
makeRequest = do 
    res <- get "http://www.example.com" 
    let resBody = res ^. responseBody :: CHA.ByteString 
    --Do stuff.... 
    return (res) 

私はこの行のCHA.ByteStringの正確な目的を理解するのに苦労しています:

let resBody = res ^. responseBody :: CHA.ByteString 

これは、明示的に型がCHA.ByteStringする必要があります述べて?あるいはそれは別の役割を果たしますか?

答えて

6

はい、これはタイプがCHA.ByteStringである必要があることを明示的に示しています。これは(単独で)ではなく、には何らかの変換がありますが、これはコンパイラ(および/または読者)のヒントであり、resにはこのタイプが必要です。

値がの多型結果の関数から生成され、多態的な引数を持つ関数でのみ消費される場合、これらの種類のローカル注釈が必要です。簡単な例:

ここ
f :: Int -> Int 
f = fromEnum . toEnum 

toEnum任意の列挙型に整数を変換する - 例えばCharとすることができます。どんなタイプを選んでも、fromEnumはそれを元に戻すことができます...問題は、どのタイプを中間結果に使うべきかを決める方法がありません!いくつかの単純な数のクラスについて

No instance for (Enum a0) arising from a use of ‘fromEnum’ 
The type variable ‘a0’ is ambiguous 
Note: there are several potential instances: 
    instance Integral a => Enum (GHC.Real.Ratio a) 
    -- Defined in ‘GHC.Real’ 
    instance Enum Ordering -- Defined in ‘GHC.Enum’ 
    instance Enum Integer -- Defined in ‘GHC.Enum’ 
    ...plus 7 others 
In the first argument of ‘(.)’, namely ‘fromEnum’ 
In the expression: fromEnum . toEnum 
In an equation for ‘f’: f = fromEnum . toEnum 

、Haskellはそう例えば、デフォルトを有しますfromIntegral . roundは自動的にIntegerを使用します。しかし、ByteStringのような型のデフォルトはないので、responseBodyのような多相結果関数では、のみ受け入れるか、明示的な注釈を追加する必要がある単形関数に結果を渡す必要がありますタイプである。

4

表記x :: T式xこれは、型クラスの存在下で必要とより高いプログラムをチェック入力するコンパイラを有効にするタイプをランク付けすることができる

Tを入力有する読み出します。たとえば:

main = print . show . read $ "1234" 

は、コンパイラが使用するオーバーロードさread機能のかを知ることができないので、あいまいです。

さらに、コンパイラが推論するタイプを絞り込むことができます。例:

1 :: Int 

最後に、このような型シグネチャは、プログラムをより読みやすくするためによく使用されます。

関連する問題