title: Does F# have 'newtype' of Haskell?
body: <h3>New Library: <a href="http://corsis.github.com/XParsec/" rel="noreferrer">XParsec</a></h3>
  
  <p>This question has lead to a stream-type-independent parsec implementation in F# 3.0 - inspired by FParsec, freed from CharStreams and simplified: <a href="http://corsis.github.com/XParsec/" rel="noreferrer">http://corsis.github.com/XParsec/</a></p>
  
  <hr>
  
  <p>In an FParsec-inspired stream-type-independent simple parsec implementation, I wonder how I could distinguish the following at the type level:</p>
  
  <ul>
  <li>parsers that consume a piece of stream</li>
  <li>parsers that work on the current position without moving ahead in the stream</li>
  </ul>
  
  <p>Specifically, how can I restrict in F#</p>
  
  <ul>
  <li><code>many1?</code></li>
  <li><code>skipMany1?'?</code></li>
  </ul>
  
  <p>to work only with parsers that are type-declared to consume streams?</p>
  
  <p>Does F# offer a similar construct to Haskell's <code>newtype</code>?</p>
  
  <p>Is there a more F#-specific way to solve this problem?</p>
  
  <h2>Code</h2>
  
  <pre class="lang-ml prettyprint-override"><code>// 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 |&gt; defaultArg i
        member e.Current           = a.[s]
        member e.Reset          () = s &lt;- -1 |&gt; defaultArg i
        member e.MoveNext       () = let i = s + 1 in if i &lt;  l then s &lt;- i; true else false
        member e.MoveBack       () = let i = s - 1 in if i &gt; -1 then s &lt;- i; true else false
        member e.State with get () = s and   set i =  if i &lt;  l then s &lt;- i       else raise &lt;| ArgumentOutOfRangeException()
        member e.Copy           ()           = new ArrayEnumerator&lt;_&gt;(a, s)
        static member inline New (a : 'a []) = new ArrayEnumerator&lt;_&gt;(a)
        interface 'a IEnumerator with
          member i.Current     = e.Current
        interface Collections.IEnumerator with
          member i.Current     = e.Current :&gt; obj
          member i.MoveNext () = e.MoveNext ()
          member i.Reset    () = e.Reset    ()
        interface IDisposable with
          member i.Dispose  () = ()
  
      type 'a IEnumerator with
        member inline e.Copy     () = (e :?&gt; 'a ArrayEnumerator).Copy     ()
        member inline e.MoveBack () = (e :?&gt; 'a ArrayEnumerator).MoveBack ()
  
      type 'a  E = 'a     IEnumerator
      type 'a AE = 'a ArrayEnumerator
      type 'a  S = 'a      E
  
    open Streams
  
    type 'a Reply      = S of 'a | F
    type 'a Reply with
      member inline r.Value   = match r with S x -&gt; x | F -&gt; raise &lt;| new InvalidOperationException()
      member inline r.IsMatch = match r with F -&gt; false | S _ -&gt; true 
      static member inline FromBool b = if b then S () else F
      static member inline Negate   r = match r with F -&gt; S () | S _ -&gt; F
      static member inline Map    f r = match r with F -&gt; F    | S x -&gt; S &lt;| f x
      static member inline Put    x r = match r with F -&gt; F    | S _ -&gt; S x
      static member inline Choose f r = match r with F -&gt; F    | S x -&gt; match f x with Some v -&gt; S v | None -&gt; F
  
    type 'a R = 'a Reply
  
    type Parser&lt;'a,'b&gt; = 'a S -&gt; 'b R
  
    module Primitives =
  
      open Operators
  
      let inline attempt (p : Parser&lt;_,_&gt;) (s : _ S) = s.Copy() |&gt; p
  
      let inline Δ&lt;'a&gt; = Unchecked.defaultof&lt;'a&gt;
      let inline pzero     (_ : _ S) = S Δ
      let inline preturn x (_ : _ S) = S x
  
      let inline current   (e : _ S) = e.Current |&gt; S
      let inline one       (e : _ S) = if e.MoveNext() then e |&gt; current else F
  
      let inline (?-&gt;) b x = if b then Some x else None
      let inline (!!&gt;) (p : Parser&lt;_,_&gt;)   e = e |&gt; p |&gt; Reply&lt;_&gt;.Negate
      let inline (|-&gt;) (p : Parser&lt;_,_&gt;) f e = e |&gt; p |&gt; Reply&lt;_&gt;.Map    f
      let inline (|?&gt;) (p : Parser&lt;_,_&gt;) f e = e |&gt; p |&gt; Reply&lt;_&gt;.Choose f
      let inline (&gt;.)  (p : Parser&lt;_,_&gt;) (q : Parser&lt;_,_&gt;) e = match p e with F -&gt; F   | S _ -&gt; q e
      let inline (.&gt;)  (p : Parser&lt;_,_&gt;) (q : Parser&lt;_,_&gt;) e = match p e with F -&gt; F   | S p -&gt; q e |&gt; Reply&lt;_&gt;.Put p
      let inline (.&gt;.) (p : Parser&lt;_,_&gt;) (q : Parser&lt;_,_&gt;) e = match p e with F -&gt; F   | S p -&gt; q e |&gt; Reply&lt;_&gt;.Map (fun q -&gt; (p,q))
      let inline (&lt;/&gt;) (p : Parser&lt;_,_&gt;) (q : Parser&lt;_,_&gt;) e = match p e with F -&gt; q e | s   -&gt; s
  
      let inline private back              (s : _ S) = s.MoveBack() |&gt; ignore
      let inline many    (p : Parser&lt;_,_&gt;) (s : _ S) = let r = ref Δ in let q = Seq.toList &lt;| seq { while (r := p s; (!r).IsMatch) do yield (!r).Value } in back s; S q
      let inline many1   (p : Parser&lt;_,_&gt;) (s : _ S) = s |&gt; many p |&gt; Reply&lt;_&gt;.Choose (function _::_ as l -&gt; Some l | _ -&gt; None)
      let inline array n (p : Parser&lt;_,_&gt;) (s : _ S) = s |&gt; many p |&gt; Reply&lt;_&gt;.Choose (function l -&gt; let a = l |&gt; List.toArray in (a.Length = n) ?-&gt; a)
  
      let inline skipMany'  (p : Parser&lt;_,_&gt;) (s : _ S) = let c = ref 0 in (while (p s).IsMatch do c := !c + 1); back s; S !c
      let inline skipMany   (p : Parser&lt;_,_&gt;) (s : _ S) = s |&gt; skipMany'  p |&gt; Reply&lt;_&gt;.Put ()
      let inline skipMany1' (p : Parser&lt;_,_&gt;) (s : _ S) = s |&gt; skipMany'  p |&gt; Reply&lt;_&gt;.Choose (fun n -&gt; if n &gt; 0 then Some n  else None)
      let inline skipMany1  (p : Parser&lt;_,_&gt;) (s : _ S) = s |&gt; skipMany1' p |&gt; Reply&lt;_&gt;.Put ()
      let inline skipN   i   p                 s        = s |&gt; skipMany'  p |&gt; Reply&lt;_&gt;.Choose (fun n -&gt; if n = i then Some () else None)
  
      let inline (!*) p s = skipMany  p s
      let inline (!+) p s = skipMany1 p s
  </code></pre>