하스켈 질문:show를 사용하도록 데이터 유형 제한
-
13-09-2019 - |
문제
암호:
data Exp a = Const a | Eq (Exp a) (Exp a)
나는 원한다 상수 a 나중에 인쇄할 수 있도록 show 유형의 값을 포함합니다.그래서 C#에서는 다음과 같이 작성합니다.
class Const : Exp { IShow X; }
class Eq : Exp { Exp X, Y; }
하스켈에서는 어떻게 할 수 있나요?
해결책
{-# LANGUAGE GADTs #-}
data Exp a where
Const :: Show a => a -> Exp a
Eq :: Exp a -> Exp a -> Exp a
다른 분기에서 다양한 데이터 유형을 허용하려면 Eq
그것도 괜찮습니다.
data Exp where
Const :: Show a => a -> Exp
Eq :: Exp -> Exp -> Exp
다른 팁
당신은 말함으로써 이것을 할 수 있습니다
data (Show a) => Exp a = Const a | Eq (Exp a) (Exp a)
그러나 이것은 거의 항상 나쁜 생각입니다. Exp
절대 사용하지 않더라도 쇼 제약 조건을 언급합니다. Show
행동 양식. 대신, 쇼 제약 조건을 관련 함수에만 적용하십시오. 보다 현실 세계 하스켈 설명을 위해.
논쟁에 대해 알고 싶은 모든 것이 있다면 Const
당신이 할 수 있다는 것입니다 show
그 결과 그 결과를 저장하지 않는 이유는 무엇입니까? String
대신 생성자의 값? 예를 들어:
data Exp = Const String | Eq Exp Expr
example = Eq (Const (show 0)) (Const (show ""))
이것은 C# 버전과 매우 유사합니다.
두 번째 질문에 답하기 위해 의견으로 묻고 Eq (Const 0) (Const "")
당신이 가진 데이터 유형으로 달성 할 수 없습니다 Exp Integer
그리고 Exp String
같은 유형이 아닙니다. 한 가지 옵션은 같은 일을하는 것입니다
data Exp = forall a . Show a => Const a | Eq Exp Exp
그것이 당신이 좋은 일을할지 여부는 유형으로 무엇을하고자하는지에 달려 있습니다.
편집 : 언급 된대로 언어 확장을 활성화해야합니다.
나는 당신의 데이터 유형을 Show 유형 클래스의 인스턴스로 선언하겠습니다.
data Exp a = Const a | Eq (Exp a) (Exp a)
instance (Show a) => Show (Exp a) where
show (Const a) = show a
show (Eq x y ) = "[ " ++ show x ++ " , " ++ show y ++ " ]"
이것을 ghci에 로드하고 다음을 수행하면 어떤 일이 발생하는지 확인하세요.
*Main> let x = Eq (Const 1) (Eq (Const 2) (Const 3))
*Main> x
[1 , [2 , 3] ]
답변 댓글:
다양한 유형을 쉽게 처리할 수 있습니다.수학적 표현식을 구문 분석한다고 가정해 보겠습니다.예를 들어 다음과 같은 구조를 가질 수 있습니다.
data Expr = Var String | Sum (Expr) (Expr) | Number Int | Prod (Expr) (Expr)
이는 숫자와 명명된 변수의 합과 곱으로 구성된 모든 표현식을 표현하는 데 충분합니다.예를 들어:
x = Sum (Var "x") (Prod (Number 5) (Var "y"))
다음을 나타냅니다:x + 5년
이것을 아름답게 인쇄하려면 다음을 수행하십시오.
instance Show Expr where
show (Var s) = show s
show (Sum x y) = (show x) ++ " + " (show y)
show (Prod x y) = (Show x) ++ (show y)
show (Number x) = show x
이것은 트릭을 할 것입니다.GADT를 사용할 수도 있습니다.
data Expr where
Var :: String -> Expr
Sum :: Expr -> Expr -> Expr
등...그런 다음 이를 Show로 인스턴스화합니다.