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