렌즈 와 GHC 를 사용하는이 이상한 코드가 있습니다 .
{-# LANGUAGE DataKinds, PolyKinds, FlexibleInstances, UndecidableInstances #-}
{-# LANGUAGE MultiParamTypeClasses #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE TypeApplications #-}
{-# LANGUAGE TypeFamilies #-}
module Main where
import Control.Lens
import GHC.Records
data Glass r = Glass -- just a dumb proxy
class Glassy r where
the :: Glass r
instance Glassy x where
the = Glass
instance (HasField k r v, x ~ r)
-- instance (HasField k r v, Glass x ~ Glass r)
=> HasField k (Glass x) (ReifiedGetter r v) where
getField _ = Getter (to (getField @k))
data Person = Person { name :: String, age :: Int }
main :: IO ()
main = do
putStrLn $ Person "foo" 0 ^. runGetter (getField @"name" the)
그 아이디어는 단지 지옥에서 벗어나는 대리자 HasField
를 불러 일으키는 사례를 가지고 ReifiedGetter
있습니다. 그러나 작동하지 않습니다.
* Ambiguous type variable `r0' arising from a use of `getField'
prevents the constraint `(HasField
"name"
(Glass r0)
(ReifiedGetter Person [Char]))' from being solved.
왜 r0
모호한 지 이해가되지 않습니다 . 나는 제약 트릭을 사용 했고 , 직감은 인스턴스 헤드가 일치해야하고 유형 검사기가 r0 ~ Person
전제 조건에서 발견 되어 모호성을 제거한다는 것입니다.
나는 변경하는 경우 (HasField k r v, x ~ r)
에 (HasField k r v, Glass x ~ Glass r)
그 제거 모호성을하고 그것을 잘 컴파일합니다. 그러나 왜 작동하고 다른 방법으로 작동하지 않습니까?