Consider a game. There are two basic data structures: players and enemy.
type Player
= { name :: String
, hp :: Number
, atk :: Number
, speed :: Number
}
type Enemy
= { name :: String
, hp :: Number
, atk :: Number
, speed :: Number
}
Now I want a structure description command
, for example
["Player", "hp", 100]
Means to set the player’s health to 100.
So i wrote this:
data Cmd = String String Number
But this is not good enough, I can enter anything, like:
Cmd "aaa" "bbb" 1
It doesn’t make sense.
After thinking about it I wrote this:
data ModuleNmae = Player | Enemy
data Cmd = Cmd ModuleNmae String Number
Looks better, but I can still write:
Cmd Player "aaa" 1
Can we use another type to describe a type?
I hope that the type of the second parameter is determined by the first parameter, and the type of the third parameter is determined by the second parameter.
As a comparison, you can write like this in typescript:
type Player = {
name: string
hp: number
atk: number
speed: number
}
type Enemy = {
name: string
hp: number
atk: number
speed: number
}
type Index = {
Player: Player
Enemy: Enemy
}
function genCmd<M extends keyof Index, K extends keyof Index[M], V extends Index[M][K]>(
moduleName: M,
key: K,
value: V,
) {}
var c1 = genCmd('Player', 'hp', 1) // ok
var c2 = genCmd('Player', 'aaa', 1) // error
var c3 = genCmd('Player', 'hp', "aaa") // error
var c4 = genCmd('aaa', 'hp', 1) // error
var c5 = genCmd('Player', 'name', 1) // error
Or the idea itself is wrong, should the logic be described in other ways?