Ur/Web 中的模块和类型类
Modules and typeclasses in Ur/Web
我正在研究 Ur/Web 中的模块,无法弄清楚如何推断标准(show、read、eq)类型类实例以及模块系统。考虑以下代码:
signature USER = sig
type id
type password
val id_read : read id
val pass_read : read password
val id_show : show id
val login : { Id : id, Password : password } -> transaction bool
val whoami : transaction (option id)
end
functor MakeUser(M : sig type id
type password
end) : USER = struct
type id = M.id
type password = M.password
table user : { Id : id, Password : password }
PRIMARY KEY Id
cookie c : { Id : id, Password : password }
fun login r =
b <- oneRowE1 (SELECT COUNT( * ) > 0
FROM user
WHERE user.Id = {[r.Id]}
AND user.Password = {[r.Password]});
if b then
setCookie c { Value = r, Expires = None, Secure = False };
return True
else return False
val whoami =
cc <- getCookie c;
case cc of
None => return None
| Some r =>
b <- oneRowE1 (SELECT COUNT( * ) > 0
FROM user
WHERE user.Id = {[r.Id]}
AND user.Password = {[r.Password]});
if b then
return (Some r.Id)
else
return None
end
structure User = MakeUser(struct
type id = string
type password = string
end)
fun main () =
me <- User.whoami;
return <xml><body>
<h1>Logged in as : {cdata (show me)}</h1>
</body></xml>
and login () =
return <xml><body>
<form>
<textbox{#Id}/>
<textbox{#Password}/>
<submit action={signin}/>
</form>
</body></xml>
and signin r =
success <- User.login { Id = readError r.Id, Password = readError r.Password };
if success then main()
else login ()
此代码编译错误
Unmatched signature item Item: val id_read : read id
Unmatched signature item Item: val password_read : read password
Unmatched signature item Item: val id_show : show id
我必须明确地在仿函数的参数中实现这些实例,还是仍然可以推断出它们?如何使这段代码工作?总的来说,我没有在 Ur.
中找到关于类型类的 "good" 文档
感谢 Adam,他指出了解决方案:
It's necessary to include lines like val id_read = _
in the functor
body.
还得加上
val inj_id : sql_injectable id
val inj_prim_id : sql_injectable_prim id
val inj_pass : sql_injectable password
到仿函数的参数签名。
所以,我最终得到了 MakeUser
函子的以下定义:
functor MakeUser(M : sig type id
type password
val id_read : read id
val pass_read : read password
val id_show : show id
val inj_id : sql_injectable id
val inj_prim_id : sql_injectable_prim id
val inj_pass : sql_injectable password
end) : USER = struct
type id = M.id
type password = M.password
val id_read = _
val pass_read = _
val id_show = _
table user : { Id : id, Password : password }
PRIMARY KEY Id
cookie c : { Id : id, Password : password }
fun login r =
b <- oneRowE1 (SELECT COUNT( * ) > 0
FROM user
WHERE user.Id = {[r.Id]}
AND user.Password = {[r.Password]});
if b then
setCookie c { Value = r, Expires = None, Secure = False };
return True
else return False
val whoami =
cc <- getCookie c;
case cc of
None => return None
| Some r =>
b <- oneRowE1 (SELECT COUNT( * ) > 0
FROM user
WHERE user.Id = {[r.Id]}
AND user.Password = {[r.Password]});
if b then
return (Some r.Id)
else
return None
end
我正在研究 Ur/Web 中的模块,无法弄清楚如何推断标准(show、read、eq)类型类实例以及模块系统。考虑以下代码:
signature USER = sig
type id
type password
val id_read : read id
val pass_read : read password
val id_show : show id
val login : { Id : id, Password : password } -> transaction bool
val whoami : transaction (option id)
end
functor MakeUser(M : sig type id
type password
end) : USER = struct
type id = M.id
type password = M.password
table user : { Id : id, Password : password }
PRIMARY KEY Id
cookie c : { Id : id, Password : password }
fun login r =
b <- oneRowE1 (SELECT COUNT( * ) > 0
FROM user
WHERE user.Id = {[r.Id]}
AND user.Password = {[r.Password]});
if b then
setCookie c { Value = r, Expires = None, Secure = False };
return True
else return False
val whoami =
cc <- getCookie c;
case cc of
None => return None
| Some r =>
b <- oneRowE1 (SELECT COUNT( * ) > 0
FROM user
WHERE user.Id = {[r.Id]}
AND user.Password = {[r.Password]});
if b then
return (Some r.Id)
else
return None
end
structure User = MakeUser(struct
type id = string
type password = string
end)
fun main () =
me <- User.whoami;
return <xml><body>
<h1>Logged in as : {cdata (show me)}</h1>
</body></xml>
and login () =
return <xml><body>
<form>
<textbox{#Id}/>
<textbox{#Password}/>
<submit action={signin}/>
</form>
</body></xml>
and signin r =
success <- User.login { Id = readError r.Id, Password = readError r.Password };
if success then main()
else login ()
此代码编译错误
Unmatched signature item Item: val id_read : read id
Unmatched signature item Item: val password_read : read password
Unmatched signature item Item: val id_show : show id
我必须明确地在仿函数的参数中实现这些实例,还是仍然可以推断出它们?如何使这段代码工作?总的来说,我没有在 Ur.
中找到关于类型类的 "good" 文档感谢 Adam,他指出了解决方案:
It's necessary to include lines like
val id_read = _
in the functor body.
还得加上
val inj_id : sql_injectable id
val inj_prim_id : sql_injectable_prim id
val inj_pass : sql_injectable password
到仿函数的参数签名。
所以,我最终得到了 MakeUser
函子的以下定义:
functor MakeUser(M : sig type id
type password
val id_read : read id
val pass_read : read password
val id_show : show id
val inj_id : sql_injectable id
val inj_prim_id : sql_injectable_prim id
val inj_pass : sql_injectable password
end) : USER = struct
type id = M.id
type password = M.password
val id_read = _
val pass_read = _
val id_show = _
table user : { Id : id, Password : password }
PRIMARY KEY Id
cookie c : { Id : id, Password : password }
fun login r =
b <- oneRowE1 (SELECT COUNT( * ) > 0
FROM user
WHERE user.Id = {[r.Id]}
AND user.Password = {[r.Password]});
if b then
setCookie c { Value = r, Expires = None, Secure = False };
return True
else return False
val whoami =
cc <- getCookie c;
case cc of
None => return None
| Some r =>
b <- oneRowE1 (SELECT COUNT( * ) > 0
FROM user
WHERE user.Id = {[r.Id]}
AND user.Password = {[r.Password]});
if b then
return (Some r.Id)
else
return None
end