pretty :: Text -> Text = id
pretty :: String -> Text = T.pack
pretty :: (Show a) => a -> Text = T.pack . show
그래서 아이디어는 이미 Show
인스턴스가 아무것도 설정 할 수 있다는 것입니다
pretty :: (Show a) => a -> Text
같은 유형의 함수의 끔찍하게 비모수 버전을 쓰고 싶습니다 Text
에 의해서만 -ing하고 있습니다. 단, Text
과 String
을 제외하고는 특별한 경우가 있습니다.
{-# LANGUAGE TypeFamilies #-}
{-# LANGUAGE MultiParamTypeClasses #-}
{-# LANGUAGE TypeSynonymInstances, FlexibleInstances, FlexibleContexts #-}
{-# LANGUAGE DataKinds, ConstraintKinds #-}
module Pretty (pretty) where
import Data.Text (Text)
import qualified Data.Text as T
type family StringLike a :: Bool where
StringLike String = True
StringLike Text = True
StringLike a = False
class (b ~ StringLike a) => Pretty' a b where
pretty' :: a -> Text
instance Pretty' String True where
pretty' = T.pack
instance Pretty' Text True where
pretty' = id
instance (Show a, StringLike a ~ False) => Pretty' a False where
pretty' = T.pack . show
type Pretty a = (Pretty' a (StringLike a))
pretty :: (Pretty a) => a -> Text
pretty = pretty'
과는 pretty
기능을 제외하고 아무것도 내 보내지 않고 사용할 수 있습니다
다음 코드는 작동합니다.
그러나, 나는 pretty
의 유형 서명에 대해 너무 행복하지 않다 :
pretty :: (Pretty a) => a -> Text
내가 StringLike
는 폐쇄 형 가족이기 때문에, GHC 알아낼 수있는 방법이 있어야한다고 생각 만 (Show a)
경우
1. The following hold trivially just by substituting the results of applying StringLike:
(StringLike String ~ True, Pretty' String True)
(StringLike Text ~ True, Pretty' Text True)
2. For everything else, we *also* know the result of applying StringLike:
(Show a, StringLike a ~ False) => (Pretty' a (StringLike a))
이의 GHC를 설득 할 수있는 방법이 있나요 : 이후, (Pretty a)
이미 만족, 보유?
'Prelude' 자격을 가져오고'Pretty'의 이름을'Show'로 변경하는 'ha-ha just serious'아이디어가 나에게 발생했습니다 ... – Cactus
"StringLike가 닫힌 타입의 패밀리이기 때문에 GHC가 (Show a)만이 보유하고있는 경우"다음과 같은 것이 큰 문제라고 생각합니다. StringLike는 일종의 종류를 산출합니다. (-lifted)'Bool','Show'는 일종의'Constraint' 타입을 산출합니다. GHC가 그 관계를 이해하지 못하는 것은 아닙니다. 그들은 실제로 다른 논리의 법칙을 따른다. Bool이 해제되면, 제외 된 중간의 법칙을 가정하지만, Constraint를 사용하면 그 법칙에 의존하지 않을 수 있습니다. –