Почему эта программа не останавливается, когда нужно только перебирать конечный поток? - PullRequest
0 голосов
/ 15 апреля 2019

Я пытаюсь получить список простых чисел из двух цифр, запустив эти коды в LearnOcaml.Коды компилируются, если я ограничиваю параметр метода listify, который возвращает список из потока, значением меньше 20. В противном случае он либо никогда не останавливается, либо возвращает «Exception: Js_of_ocaml__Js.Error _.».Я не думаю, что код семантически неверен.Поэтому мне интересно, может ли кто-нибудь помочь решить проблему?

type 'a stream = Eos | StrCons of 'a*(unit -> 'a stream)



(*integers from n onwards*)
let rec nums_from n =
  StrCons(n,fun () -> nums_from (n+1))



let rec filterStr (test : 'a -> bool) (s: 'a stream) =
  match s with
  |Eos -> Eos
  |StrCons(q,w) -> if test q then StrCons(q,fun ()-> filterStr test (w ()))
      else filterStr test (w ())  

(*Remove all numbers mod p*)
let sift p =
  filterStr (fun x -> x mod p <> 0)

(*Sieves*)
let rec sieves s =
  match s with
  |Eos ->Eos
  |StrCons(x,g) -> StrCons(x, fun ()-> sieves (sift x (g ())))


(*primes*) 
let allprimes = sieves (nums_from 2) 

let rec listify s n=
  if n =0 then [] else
    match s with
    |Eos -> []
    |StrCons(q,w) -> q::(listify (w ()) (n-1))

let twodigitsprimes = filterStr (fun x -> x > 10&& x<100) allprimes

let twodigitsprimeslist= listify twodigitsprimes 21

1 Ответ

0 голосов
/ 15 апреля 2019

Похоже, что filterStr зацикливается при попытке создать StrCons, который представляет следующий элемент после 21-го. Так как есть только 21 двузначное простое число, это зациклится навсегда.

Обратите внимание, что когда listify вызывается с n = 0, StrCons уже создан; это просто не исследовано. Но StrCons для этого случая расходится (и OCaml - строгий язык).

Вы можете заставить работать вещи, используя эту версию listify:

let rec listify s n =
  if n = 0 then []
  else
    match s with
    | Eos -> []
    | StrCons (q, w) ->
        if n = 1 then [q] else q :: listify (w ()) (n - 1)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...