mới nhất (2.8.0.0) định nghĩa cho Dec
có constructor dụ sau:Mẫu Haskell có thể tạo ra các cá thể kiểu chữ nổi đa param không?
InstanceD Cxt Type [Dec]
Có vẻ như là chỉ có một loại có thể được khởi tạo. Có cách nào để làm việc này?
mới nhất (2.8.0.0) định nghĩa cho Dec
có constructor dụ sau:Mẫu Haskell có thể tạo ra các cá thể kiểu chữ nổi đa param không?
InstanceD Cxt Type [Dec]
Có vẻ như là chỉ có một loại có thể được khởi tạo. Có cách nào để làm việc này?
Có, các loại loại đa thông số được hỗ trợ.
Hơi gây nhầm lẫn, lập luận Type
đề cập đến toàn bộ đầu dụ, và, mặc dù nó không thực sự là một loại, có vẻ như đủ một cú pháp mà loại Type
được tái sử dụng cho mục đích này.
Do đó, nếu bạn đang tạo ra một đa thông số instance Foo Int Bool
, bạn cần phải sử dụng "loại" Foo Int Bool
, xây dựng ví dụ như thế này:
(ConT (mkName "Foo") `AppT` ConT (mkName "Int")) `AppT` ConT (mkName "Bool")
Dưới đây là một ví dụ hoàn chỉnh:
{-# LANGUAGE MultiParamTypeClasses, TemplateHaskell #-}
import Language.Haskell.TH
class Foo a b where
foo :: (a, b)
$(return [InstanceD [] (((ConT (mkName "Foo")) `AppT` ConT (mkName "Int")) `AppT` ConT (mkName "Bool"))
[ValD (VarP (mkName "foo"))
(NormalB (TupE [LitE (IntegerL 42), ConE (mkName "False")])) []]])
main = print (foo :: (Int, Bool))
Cách dễ dàng để trả lời câu hỏi này và tương tự là sử dụng runQ
với định nghĩa ghép nối. Ví dụ: ghci:
$ ghci
GHCi, version 7.4.1: http://www.haskell.org/ghc/ :? for help
Prelude> :set -XTemplateHaskell
Prelude> :set -XMultiParamTypeClasses
Prelude> import Language.Haskell.TH
Prelude Language.Haskell.TH> class Class a b where
Prelude Language.Haskell.TH> runQ [d| instance Class Int Bool where |]
[InstanceD [] (AppT (AppT (ConT :Interactive.Class) (ConT GHC.Types.Int)) (ConT GHC.Types.Bool)) []]
Điều này thể hiện hình thức chính xác cần thiết, thay thế Class
với bất kỳ lớp học nào bạn đang sử dụng.