Конструкторы типа высшего порядка и функторы в Ocaml

все вышесказанное верно. Пожалуйста, будьте уверены, прежде чем это число в строке, сделав «typeot x === 'number», «другой мудрый он вернет NaN

 var num = "fsdfsdf242342";
 typeof num => 'string';

 var num1 = "12423";
 typeof num1 => 'number';
 +num1 = > 12423`
28
задан sdcvvc 1 January 2010 в 03:06
поделиться

3 ответа

Haskell допускает переменные более высокого типа. Диалекты ML, в том числе и Caml, допускают только переменные типа "*". Переведено на простой английский язык,

  • В Haskell переменная типа g может соответствовать "конструктору типов" типа Может быть или IO или спискам. Таким образом, g x в вашем примере с Хаскеллом будет нормально (жаргон: "доброжелательно"), если, например, g это может быть и x это Integer.

  • В ML переменная типа 'g может соответствовать только "типу земли", как int или string, но никогда не может соответствовать конструктору типа, как опция или list. Поэтому никогда не правильно пытаться применить переменную типа к другому типу.

Насколько мне известно, в ML нет глубоких оснований для этого ограничения. Наиболее вероятным объяснением является исторический случай. Когда Милнер изначально придумал свои идеи о полиморфизме, он работал с очень простыми переменными типа, стоящими только для монотипов вида *. Ранние версии Хаскелла делали то же самое, а затем в какой-то момент Марк Джонс обнаружил, что делать выводы о типах переменных на самом деле довольно просто. Haskell был быстро переработан, чтобы позволить переменные более высокого типа, но ML никогда не догонял.

Люди в INRIA внесли много других изменений в ML, и я немного удивлен, что они никогда не делали этого. Когда я программирую на ML, мне, возможно, нравится иметь переменные более высокого типа. Но их нет, и я не знаю, как кодировать те примеры, о которых вы говорите, кроме как с помощью functors .

34
ответ дан 28 November 2019 в 03:06
поделиться

Вы можете сделать это, но вам нужно сделать немного хитрости:

newtype Fix f = In{out:: f (Fix f)}

Вы можете определить Cata впоследствии:

Cata :: (Functor f) => (f a -> a) -> Fix f -> a
Cata f = f.(fmap (cata f)).out

Это определит общий катаморфизм для всех функторы, которые вы можете использовать для создания своих собственных вещей. Пример:

data ListFix a b = Nil | Cons a b
data List a = Fix (ListFix a)
instance functor (ListFix a) where
fmap f Nil = Nil
fmap f (Cons a lst) = Cons a (f lst)
-1
ответ дан Fruchtzwerg 20 November 2019 в 02:58
поделиться

Вы можете сделать что-то подобное в OCaml, используя модули вместо типов и функторы (модули высшего порядка) вместо типов высшего порядка. Но это выглядит намного уродливее и не имеет возможности определения типа, поэтому вам придется вручную указывать много вещей.

module type Type = sig
  type t
end

module Char = struct
  type t = char
end

module List (X:Type) = struct
  type t = X.t list
end

module Maybe (X:Type) = struct
  type t = X.t option
end

(* In the following, I decided to omit the redundant
   single constructors "Id of ...", "Compose of ...", since
   they don't help in OCaml since we can't use inference *)

module Id (X:Type) = X

module Compose
  (F:functor(Z:Type)->Type)
  (G:functor(Y:Type)->Type)
  (X:Type) = F(G(X))

let l : Compose(List)(Maybe)(Char).t = [Some 'a']

module Example2 (F:functor(Y:Type)->Type) (X:Type) = struct
  (* unlike types, "free" module variables are not allowed,
     so we have to put it inside another functor in order
     to scope F and X *)
  let iso (a:Compose(Id)(F)(X).t) : F(X).t = a
end
22
ответ дан newacct 20 November 2019 в 02:58
поделиться
Другие вопросы по тегам:

Похожие вопросы: