Jadi saya menulis permainan sepak bola kecil ini untuk beberapa waktu sekarang, dan ada satu hal yang mengganggu saya sejak awal. Game ini mengikuti Yampa Arcade polanya, jadi ada tipe penjumlahan untuk "objek" di dalam game:
data ObjState = Ball Id Pos Velo
| Player Id Team Number Pos Velo
| Game Id Score
Objek bereaksi terhadap pesan, jadi ada tipe penjumlahan lainnya:
data Msg = BallMsg BM
| PlayerMsg PM
| GameMsg GM
data BM = Gained | Lost
data PM = GoTo Position | Shoot
data GM = GoalScored | BallOutOfBounds
Kerangka kerja Yampa bergantung pada apa yang disebut fungsi sinyal. Dalam kasus kami, terdapat fungsi sinyal untuk perilaku bola, pemain, dan permainan. Disederhanakan secara kasar:
ballObj, playerObj, gameObj :: (Time -> (GameInput, [Msg]))
-> (Time -> (ObjState, [(Id, Msg)]))
Jadi mis. ballObj mengambil fungsi yang menghasilkan GameInput (sentuhan tombol, status permainan, ...) dan daftar pesan khusus untuk bola pada waktu tertentu, dan mengembalikan fungsi yang menghasilkan status bola dan pesannya ke objek lain (bola , permainan, pemain) pada waktu tertentu. Di Yampa, tanda tangan tipe sebenarnya terlihat sedikit lebih bagus:
ballObj, playerObj, gameObj :: SF (GameInput, [Msg]) (ObjState, [(Id, Msg)])
Tanda tangan tipe seragam ini penting untuk kerangka Yampa: (sekali lagi, disederhanakan dengan sangat kasar) ia membangun fungsi sinyal besar dari daftar fungsi sinyal 11 + 11 (pemain) + 1 (bola) + 1 (permainan) dengan tipe yang sama (melalui dpSwitch) yang kemudian dijalankan (melalui pengaktifan kembali).
Jadi sekarang, apa yang mengganggu saya: Masuk akal untuk mengirim BallMsg ke Ball, atau PlayerMsg ke Player. Jika seseorang mengirim misalnya GameMsg ke Ball, programnya akan crash. Apakah tidak ada cara untuk menempatkan pemeriksa tipe untuk menghindari hal ini? Saya baru-baru ini membaca Pokemon yang bagus ini posting tentang keluarga tipe, dan sepertinya ada beberapa analogi. Jadi mungkin ini bisa menjadi titik awal:
class Receiver a where
Msg a :: *
putAddress :: Msg a -> a -> Msg a
data BallObj = ...
data GameObj = ...
data PlayerObj = ...
instance Receiver BallObj where
Msg BallObj = Gained | Lost
(...)
Sekarang, fungsi SF mungkin terlihat seperti ini:
forall b . (Receiver a, Receiver b) => SF (GameInput, [Msg a]) (a, [(b, Msg b)])
Apakah ini akan membawaku kemana saja?
[Msg]
, bagaimana kerangka kerja mengetahui pesan mana yang masuk ke objek mana? - person n. 1.8e9-where's-my-share m.   schedule 23.05.2013