수색…


프록시 사용

Data.Proxy 있는 Proxy :: k -> * 유형은 컴파일러에 유형 정보 (예 : 유형 클래스 인스턴스를 선택하는 경우)를 제공해야 할 때 사용됩니다. 이는 런타임에도 관계가 없습니다.

{-# LANGUAGE PolyKinds #-}

data Proxy a = Proxy

Proxy 를 사용하는 함수는 일반적으로 ScopedTypeVariables 를 사용하여 a 유형을 기반으로 유형 클래스 인스턴스를 선택합니다.

예를 들어 모호한 함수의 고전적인 예제,

showread :: String -> String
showread = show . read

elaborator가 ShowRead 의 어느 인스턴스를 사용하는지 알지 못하기 때문에 타입 에러가 발생합니다. 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 있는 범위에 faProxy :: Proxy a 경우 f 호출 할 때 Proxy :: Proxy a 를 작성할 필요가 없습니다.

ghci> let chars = "foo"  -- chars :: [Char]
ghci> showread chars "'a'"
"'a'"

프록시는 ()와 같습니다.

Proxy 에는 런타임 정보가 없으므로 언제든지 임의의 f 대해 자연스러운 변환 fa -> Proxy a 를 작성할 수 있습니다.

proxy :: f a -> Proxy a
proxy _ = Proxy

주어진 값을 항상 () 로 지울 수있는 것과 같습니다.

unit :: a -> ()
unit _ = ()

기술적으로, Proxy 는 Functor의 범주에있는 터미널 객체입니다. () 는 값의 범주에있는 터미널 객체입니다.



Modified text is an extract of the original Stack Overflow Documentation
아래 라이선스 CC BY-SA 3.0
와 제휴하지 않음 Stack Overflow