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