首页 > 解决方案 > Ur/Web 中的模块和类型类

问题描述

我正在使用Ur/Web中的模块,但无法弄清楚如何推断标准(显示、读取、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 中找到关于类型类的“好”文档。

标签: modulesmlml

解决方案


感谢Adam,他向我指出了解决方案:

有必要val id_read = _在仿函数体中包含行。

也不得不添加

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

推荐阅读