Ur / Web中的模块和类型类

时间:2018-11-29 12:20:48

标签: module sml ml

我正在使用Ur/Web中的模块,并且无法弄清楚如何与模块系统一起推断标准(显示,读取,等效)类型类实例。考虑以下代码:

db.collection.aggregate([
  { "$project": {
    "matches": {
      "$size": {
        "$setIntersection": [
          [ "a", "b", "d"],
          "$tags.name"
        ]
      }
    }
  }}
])

此代码无法编译错误

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 ()

我是否必须在函子的参数中明确实现这些实例,否则仍然可以推断它们?如何使此代码起作用?通常,我在Ur中找不到关于类型类的“好”文档。

1 个答案:

答案 0 :(得分:1)

感谢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