はい、可能です。
なぜかというと、データ型を定義する際にデータ構築子が引数を取るようにできるためです。
いま、以下の定義です。
haskell
1data JSONValueType
2 = JSONString
3 | JSONNumber
4 | JSONBoolean
5 | JSONArray
6 | JSONObject
7 | JSONNull
8 deriving (Show, Eq)
9
10data JSONToken
11 = JSONValueType
12 | KEY
13 | COLON
14 | COMMA
15 | OBJECT_OPEN
16 | OBJECT_CLOSE
17 | ARRAY_OPEN
18 | ARRAY_CLOSE
19 deriving (Show, Eq)
ここでデータ型JSONValueType
の名前とデータ型JSONToken
のデータ構築子の1つJSONValueType
が同名でやや紛らわしいため、後者をVALUE
に改名します。
haskell
1data JSONToken
2 = VALUE -- 改名
3 | KEY
4 | COLON
5 | COMMA
6 | OBJECT_OPEN
7 | OBJECT_CLOSE
8 | ARRAY_OPEN
9 | ARRAY_CLOSE
10 deriving (Show, Eq)
そして「JSONのトークンを表す型が、JSONの値を表す型を内包するように定義したい」ため、JSONのトークンを表す型であるJSONToken
の一部のデータ構築子が型JSONValueType
の値を取れるようにします。
haskell
1data JSONToken
2 = VALUE JSONValueType -- 追加
3 | KEY
4 | COLON
5 | COMMA
6 | OBJECT_OPEN
7 | OBJECT_CLOSE
8 | ARRAY_OPEN
9 | ARRAY_CLOSE
10 deriving (Show, Eq)
動かしてみましょう。
shell
1$ ghci main.hs
2GHCi, version 8.10.7: https://www.haskell.org/ghc/ :? for help
3...
4Ok, one module loaded.
5*Main> :t KEY
6KEY :: JSONToken
7*Main> :t VALUE
8VALUE :: JSONValueType -> JSONToken
9*Main> :t VALUE JSONString
10VALUE JSONString :: JSONToken
データ構築子KEY
は引数を取らずして型JSONToken
であるのに対し、VALUE
のほうはJSONValueType
の値を取り、これも型JSONToken
になりました。
なお、余談ですがデータ型の定義方法には以下の形もあります。
こちらのほうがデータ構築子が引数を取る様子を見やすいかもしれません。
haskell
1{-# LANGUAGE GADTs #-}
2
3...
4
5data JSONToken where
6 VALUE :: JSONValueType -> JSONToken
7 KEY :: JSONToken
8 COLON :: JSONToken
9 COMMA :: JSONToken
10 OBJECT_OPEN :: JSONToken
11 OBJECT_CLOSE :: JSONToken
12 ARRAY_OPEN :: JSONToken
13 ARRAY_CLOSE :: JSONToken
参照: Haskell 2010 Language Report > 4.2.1 Algebraic Datatype Declarations
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。