Tôi đang làm việc với các ngôn ngữ được nhúng trong Haskell. Ngôn ngữ của tôi có thể được in ra dưới dạng mã nguồn, vì vậy tôi đã tạo một lớp Compile
và tạo một cá thể lớp cho mọi phần tử chương trình có thể được in ra. Bằng cách đó tôi có thể đổ mã của tôi một cách thành phần. Điều này làm việc tốt trước khi các khái niệm về chế độ được xem xét.Haskell: Ứng dụng gia đình từ đồng nghĩa không hợp lệ trong ví dụ
Mỗi ngôn ngữ có thể được sử dụng ở hai chế độ (được triển khai dưới dạng các thể hiện của lớp Mode
). Trong chế độ đơn giản, mọi thứ đều bình thường. Ở chế độ có tên, rất nhiều phần tử chương trình có thể được thay thế bằng các chuỗi. (Nó hoạt động như định nghĩa macro.)
Tôi muốn giữ tất cả các biểu diễn an toàn loại. Vì vậy, các yếu tố chương trình của các ngôn ngữ khác nhau hoặc các chế độ khác nhau không thể được trộn lẫn.
Vì vậy, vấn đề là: làm thế nào để đổ các ngôn ngữ bất kể chế độ?
{-# LANGUAGE TypeFamilies, MultiParamTypeClasses, FlexibleInstances #-}
class Compile a where
comp :: a -> String
-- common elements in all languages
data ElemA l m = ElemA (ElemB l m)
data ElemB l m = ElemB
class Lang l where
-- language-specific elements
data Instructions l :: * -> *
-- common modes for all languages
class Mode l m where
type MElemA l m :: *
type MElemB l m :: *
-- mode with normal program elements
data SimpleMode
instance Mode l SimpleMode where
type MElemA l SimpleMode = ElemA l SimpleMode
type MElemB l SimpleMode = ElemB l SimpleMode
-- a mode where each program element can be replaced with a string
data NamedMode
instance Mode l NamedMode where
type MElemA l NamedMode = Either String (ElemA l NamedMode)
type MElemB l NamedMode = Either String (ElemB l NamedMode)
-- definition of Lang1 language
data Lang1
instance Lang Lang1 where
data Instructions Lang1 m
= Add (MElemA Lang1 m) (MElemA Lang1 m) (MElemA Lang1 m)
| Mul (MElemA Lang1 m) (MElemA Lang1 m) (MElemA Lang1 m)
-- | ...
-- dumping the source code of Lang1 langauge
-- ILLEGAL TYPE SYNONYM FAMILY APPLICATION HERE
instance Compile (MElemA Lang1 m) where
comp _ = "A"
-- AND HERE
instance Compile (MElemB Lang1 m) where
comp _ = "B"
Tôi biết rằng các loại từ đồng nghĩa không hoạt động tốt với các lớp, vì vậy tôi đang tìm giải pháp khác.
giải phápCó thể tôi biết (nhưng không muốn sử dụng):
- Sử dụng nhiều chức năng thay vì một đơn đa hình
comp
chức năng. - Chỉ sử dụng
NamedMode
cho đại diện
Cũng nhờ đề cập đến những điểm tương đồng với câu hỏi này khác: http://stackoverflow.com/questions/2590495/problem-when-mixing-type-classes-and-type-families?rq=1 –
Could đã sử dụng newtype thay cho dữ liệu - không? – lynnard