Kullanım durumu: Oyunun kurallarını her iki tarafta kodlayabilmem ve durum değişiklikleriyle iletişim kurabilmem için bir ghcjs ön ucunda ve temelde aynı durumu kullanan bir arka uçta bir oyun yazıyorum. . Bu amaçla, bir oyun sahası, her bir oyuncunun bizim tarafımızdan ve ussr tarafından temsil edildiği yerde bir bakıma benzeyecekti. Her oyuncunun bir eli var ve sunucu bakış açısından gayet yeterli ve her iki oyuncunun elinde her kartı biliyor. Ama bize, oyuncunun bakış açısından, gamestate buTürü aileler belirsiz değişken hatasına neden olur
data GameState = GameState {
-- public stuff
usHand :: [Card],
ussrHand :: Int
}
gibi daha, kendi eli görebilirsiniz, ama sadece rakibi kaç kartları görebilirsiniz görünüyor. Bir gözlemci daha az görür. Oyunun kuralları karmaşıktır ve çok fazla şey olabilir, bu yüzden kuralları bir kez kodlamak harika olurdu, öyle ki yeni kartlar gibi oyuncunun elini etkileyen kurallar göstermek için bir oyuncuyu zorlamak gibi Bir türdeki kart, vs., her bir eli, kim olduklarına göre uygun şekilde etkiler. Bu amaçla, her iki hatlarında 75 üzerinde
{-# LANGUAGE TypeFamilies, RankNTypes #-}
module Test where
data Card = Card
data BoardState = BoardState
data GamePhase = GamePhase
data Country
data Player = PUS | PUSSR
data US
data USSR
data Observer
data Server
data Private = Private Int
data Public = Public [Card]
class HandType a where
type USHand a :: *
type USSRHand a :: *
toUS :: Public -> USHand a
-- toUSSR :: Public -> USSRHand a -- TODO
instance HandType Server where
type USHand Server = Public
type USSRHand Server = Public
toUS (Public cs) = Public cs
instance HandType US where
type USHand US = Public
type USSRHand US = Private
toUS (Public cs) = Public cs
instance HandType USSR where
type USHand USSR = Private
type USSRHand USSR = Public
toUS (Public cs) = Private (length cs)
instance HandType Observer where
type USHand Observer = Private
type USSRHand Observer = Private
toUS (Public cs) = Private (length cs)
data GameState a = GameState {
gameTurn :: Int, -- | Everyone sees
gamePhase :: GamePhase, -- | this
boardState :: BoardState, -- | stuff
usHand :: USHand a,
ussrHand :: USSRHand a
}
data Event a =
PlaceInfluence Player Int Country -- | Most plays don't affect
| PlayCard Player Card -- | either hand
| DealCards (USHand a) (USSRHand a) -- | This one does
-- Works
obsEvents :: [Event US]
obsEvents = [PlayCard PUS Card, PlayCard PUSSR Card, DealCards (Public [Card]) (Private 3)]
-- Works
serverEvents :: [Event Server]
serverEvents = [PlayCard PUS Card, PlayCard PUSSR Card, DealCards (Public [Card, Card]) (Public [Card])]
-- The server must send out the gamestate modified for the player's consumption.
-- serverToPlayerGS :: GameState Server -> GameState a
serverToPlayerGS (GameState turn phase bs us ussr) =
GameState turn phase bs (toUS us) undefined -- | <- Doesn't work (line 75)
-- serverToPlayerEvent :: Event Server -> Event a
serverToPlayerEvent (PlaceInfluence p amt c) = PlaceInfluence p amt c
serverToPlayerEvent (PlayCard p c) = PlayCard p c
serverToPlayerEvent (DealCards us ussr) =
DealCards (toUS us) undefined -- | <- Doesn't work (line 78)
hata çalışmak ve 78
Couldn't match expected type ‘USHand a’
with actual type ‘USHand a0’
NB: ‘USHand’ is a type function, and may not be injective
The type variable ‘a0’ is ambiguous
Relevant bindings include
serverToPlayerGS :: GameState Server -> GameState a
(bound at src/Test4.hs:74:1)
In the fourth argument of ‘GameState’, namely ‘(toUS us)’
In the expression: GameState turn phase bs (toUS us) undefined
Veya eğer çizgisinde her ikisi şey vardır etmeyen, tip ailelerini kullanarak aşağıdaki yazma sona erdi Ben
Could not deduce (USHand a0 ~ USHand a1)
from the context (HandType a1,
USHand a1 ~ USHand a,
USHand t ~ Public)
bound by the inferred type for ‘serverToPlayerGS’:
(HandType a1, USHand a1 ~ USHand a, USHand t ~ Public) =>
GameState t -> GameState a
at src/Test4.hs:(74,1)-(75,45)
NB: ‘USHand’ is a type function, and may not be injective
The type variable ‘a0’ is ambiguous
Expected type: USHand a
Actual type: USHand a0
When checking that ‘serverToPlayerGS’ has the inferred type
serverToPlayerGS :: forall t a a1.
(HandType a1, USHand a1 ~ USHand a, USHand t ~ Public) =>
GameState t -> GameState a
Probable cause: the inferred type is ambiguous
Ben benzer sitedeki bazı diğer yanıtları görmek bir tür deklarasyonu ihmal, ancak düzeltmeler sonuçta bir yöntemdir ben umut ediyorum cevap, yol açacağını açıkladı nasıl emin değilim t o serverToPlayerGS ve serverToPlayerEvent komutlarını yazım kurallarına göre yazıp kullanışlıdır.
Bu tamamen çalışır. Çok teşekkürler! Ayrıca, Proxy türünün ghc'nin gelecekteki bir sürümünün gerekli olmayabileceğini duydum. Bu konuda herhangi bir bilgi için herhangi bir referans var mı? –
@mindreader, Evet 'TypeApplication' uzantısı budur. Mevcut bir tahliye adayına sahip olan GHC 8'e inecek. https://ghc.haskell.org/trac/ghc/wiki/TypeApplication – hao