Есть ли у F # новый тип Haskell?
Новая библиотека:XParsec
Этот вопрос привел к реализации независимой от типа потока реализации парсек в F # 3.0, вдохновленной FParsec, освобожденной от CharStreams и упрощенной:http://corsis.github.com/XParsec/
Интересно, как в реализации простого парсека, независимой от типа потока, вдохновленной FParsec, я мог бы различить следующее на уровне типов:
парсеры, которые потребляют кусок потокапарсеры, которые работают на текущей позиции, не двигаясь вперед в потокеВ частности, как я могу ограничить в F #
many1?
skipMany1?'?
работать только с синтаксическими анализаторами, которые объявлены по типу для использования потоков?
Предлагает ли F # подобную конструкцию для Haskell?newtype
Есть ли более специфичный для F # способ решения этой проблемы?
Код// Copyright (c) Cetin Sert 2012
// License: Simplified BSD.
#if INTERACTIVE
#else
module XParsec
#endif
open System
open System.Collections.Generic
module Streams =
type 'a ArrayEnumerator (a : 'a [], ?i : int) as e =
let l = a.Length
let mutable s = -1 |> defaultArg i
member e.Current = a.[s]
member e.Reset () = s defaultArg i
member e.MoveNext () = let i = s + 1 in if i < l then s -1 then s raise false | S _ -> true
static member inline FromBool b = if b then S () else F
static member inline Negate r = match r with F -> S () | S _ -> F
static member inline Map f r = match r with F -> F | S x -> S F | S _ -> S x
static member inline Choose f r = match r with F -> F | S x -> match f x with Some v -> S v | None -> F
type 'a R = 'a Reply
type Parser = 'a S -> 'b R
module Primitives =
open Operators
let inline attempt (p : Parser) (s : _ S) = s.Copy() |> p
let inline Δ
let inline pzero (_ : _ S) = S Δ
let inline preturn x (_ : _ S) = S x
let inline current (e : _ S) = e.Current |> S
let inline one (e : _ S) = if e.MoveNext() then e |> current else F
let inline (?->) b x = if b then Some x else None
let inline (!!>) (p : Parser) e = e |> p |> Reply.Negate
let inline (|->) (p : Parser) f e = e |> p |> Reply.Map f
let inline (|?>) (p : Parser) f e = e |> p |> Reply.Choose f
let inline (>.) (p : Parser) (q : Parser) e = match p e with F -> F | S _ -> q e
let inline (.>) (p : Parser) (q : Parser) e = match p e with F -> F | S p -> q e |> Reply.Put p
let inline (.>.) (p : Parser) (q : Parser) e = match p e with F -> F | S p -> q e |> Reply.Map (fun q -> (p,q))
let inline () (p : Parser) (q : Parser) e = match p e with F -> q e | s -> s
let inline private back (s : _ S) = s.MoveBack() |> ignore
let inline many (p : Parser) (s : _ S) = let r = ref Δ in let q = Seq.toList many p |> Reply.Choose (function _::_ as l -> Some l | _ -> None)
let inline array n (p : Parser) (s : _ S) = s |> many p |> Reply.Choose (function l -> let a = l |> List.toArray in (a.Length = n) ?-> a)
let inline skipMany' (p : Parser) (s : _ S) = let c = ref 0 in (while (p s).IsMatch do c := !c + 1); back s; S !c
let inline skipMany (p : Parser) (s : _ S) = s |> skipMany' p |> Reply.Put ()
let inline skipMany1' (p : Parser) (s : _ S) = s |> skipMany' p |> Reply.Choose (fun n -> if n > 0 then Some n else None)
let inline skipMany1 (p : Parser) (s : _ S) = s |> skipMany1' p |> Reply.Put ()
let inline skipN i p s = s |> skipMany' p |> Reply.Choose (fun n -> if n = i then Some () else None)
let inline (!*) p s = skipMany p s
let inline (!+) p s = skipMany1 p s