Haskell Language
プロキシ
サーチ…
プロキシの使用
Data.ProxyにあるProxy :: k -> *型は、コンパイラにいくつかの型情報を渡す必要があるとき(たとえば、型クラスインスタンスを選択するときなど)に使用されますが、それは実行時には関係ありません。
{-# LANGUAGE PolyKinds #-}
data Proxy a = Proxy
Proxyを使用する関数は通常、 ScopedTypeVariablesを使用してa型に基づいて型クラスインスタンスを選択します。
例えば、あいまいな関数の古典的な例は、
showread :: String -> String
showread = show . read
エラボレータがShowまたはReadインスタンスを使用するかRead知らないために型エラーが発生し、 Proxyを使用して解決できます。
{-# LANGUAGE ScopedTypeVariables #-}
import Data.Proxy
showread :: forall a. (Show a, Read a) => Proxy a -> String -> String
showread _ = (show :: a -> String) . read
Proxyで関数を呼び出すときには、型名を使用してaあなたが意味するものを宣言する必要があります。
ghci> showread (Proxy :: Proxy Int) "3"
"3"
ghci> showread (Proxy :: Proxy Bool) "'m'" -- attempt to parse a char literal as a Bool
"*** Exception: Prelude.read: no parse
"多型プロキシ"イディオム
Proxyには実行時情報が含まれていないため、 Proxyコンストラクタでパターンマッチングする必要はありません。だから一般的なイディオムは、型変数を使ってProxyデータ型を抽象化することです。
showread :: forall proxy a. (Show a, Read a) => proxy a -> String -> String
showread _ = (show :: a -> String) . read
さて、あるfスコープにfaがあると、 f呼び出すときにProxy :: Proxy aを書く必要はありません。
ghci> let chars = "foo" -- chars :: [Char]
ghci> showread chars "'a'"
"'a'"
プロキシはlikeです()
Proxyにはランタイム情報が含まれていないので、任意のf自然な変換fa -> Proxy aを書くことができます。
proxy :: f a -> Proxy a
proxy _ = Proxy
これは、任意の値を常に()消去する方法と同じです。
unit :: a -> ()
unit _ = ()
技術的には、 Proxyはファンクタのカテゴリの端末オブジェクトであり、 ()は値のカテゴリの端末オブジェクトです。
Modified text is an extract of the original Stack Overflow Documentation
ライセンスを受けた CC BY-SA 3.0
所属していない Stack Overflow