2017-02-21 31 views
1

Я хотел бы представить некоторое скалярное значение (например, целые числа или строки) либо по его реальному значению, либо по некоторому значению NA, а затем хранить их в коллекции (например, в списке). Цель состоит в том, чтобы обрабатывать отсутствующие значения.OCaml Подпись с несколькими типами

Чтобы сделать это, я реализовал подпись

module type Scalar = sig 
    type t 
    type v = Value of t | NA 
end 

Теперь у меня есть некоторые полиморфный Vector тип в виду, что содержит Scalar с. В основном, некоторые из следующих

module Make_vector(S: Scalar) = struct 
    type t = S.v list 

    ... rest of the functor ... 
end 

Однако я не могу заставить это работать. Я хотел бы сделать что-то вроде

module Int_vector = Make_vector(
    struct 
     type t = int 
    end 
) 

module Str_vector = Make_vector(
    struct 
     type t = string 
    end 
) 

... and so on for some types. 

Я еще не работал много с OCaml, так может быть, это не правильный путь. Любые советы о том, как реализовать такой полиморфный Скаляр с типом суммы?

Компилятор всегда отвечает следующим сообщением:

The parameter cannot be eliminated in the result type. 
Please bind the argument to a module identifier. 

Раньше я пытался реализовать Scalar как тип суммы, но столкнулся с вопросами сложности при реализации некоторых функций из-за огромных match статей. Другой вариант (imo not so nice) - использовать option. Это лучшая стратегия?

ответ

0

Насколько я могу судить, вы структурируете v как тип ввода для вашего функтора, но вы действительно хотите, чтобы он был типом вывода. Затем, когда вы применяете функтор, вы указываете только тип t, но не v. Мое предложение состоит в том, чтобы переместить определение v в вашу реализацию Make_vector.

+0

не думал об этом! Теперь это работает. Благодаря :) – teekay

0

Что вы пытаетесь сделать точно с помощью модулей/функторов? Почему простой 'a option list не достаточно хорош? На нем могут работать функции, например.

let rec count_missing ?acc:(acc=0) = function 
    | None::tail -> count_missing ~acc:(acc+1) tail 
    | _::tail -> count_missing ~acc tail 
    | [] -> acc ;; 


val count_missing : ?acc:int -> 'a option list -> int = <fun> 

count_missing [None; Some 1; None; Some 2] ;; 
- : int = 2 

count_missing [Some "foo"; None; Some "bar"] ;; 
- : int = 1