Модули и классы типов в Ur / Web - PullRequest
0 голосов
/ 29 ноября 2018

Я играю с модулями в 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.

1 Ответ

0 голосов
/ 29 ноября 2018

Спасибо Адаму , который указал мне на решение:

Необходимо включить такие строки, как 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:

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
...