So all you need is a program that checks if your functions terminate. How hard can it be, right? ;)šSeriously though, since you would need static termination guarantees on all functions that produce lists, you will bešseverelyšrestricted when working with them. It&#39;s like Haskell without general recursion...<br>
<br>Anyway, here&#39;s a quick version where you can do cons, map and ++. The idea is that any function that results in a larger list also results in a larger type. Any function that works on finite lists of type a can have type &quot;Finite s a&quot; as a parameter and since the finite module only exports the limited : and ++ functions it should be safe. The inferred type of &quot;safeLength = length . infinite&quot; is &quot;safeLength :: Finite s a -&gt; Int&quot; for instance.<div>
<br><font class="Apple-style-span" face="&#39;courier new&#39;, monospace">{-# Language EmptyDataDecls #-}<br><br>module Finite (<br> š šemp<br> š, (-:)<br> š, map<br> š, (++)<br> š, infinite<br> š, module Prelude<br> š) where<br>
<br>import Prelude hiding ((++), map)<br>import qualified Prelude<br><br>data Z<br>data S a<br>data Plus a b<br><br>newtype Finite s a = Finite {infinite :: [a]} deriving Show<br><br>instance Functor (Finite n) where<br> šfmap f = Finite . fmap f . infinite<br>
<br>emp :: Finite Z a<br>emp = Finite []<br><br>(-:) :: a -&gt; Finite n a -&gt; Finite (S n) a <br>(-:) a l = Finite $ a š: (infinite l)<br>infixr 5 -:<br><br>(++) :: Finite s1 a -&gt; Finite s2 a -&gt; Finite (S (Plus s1 s2)) a<br>
(++) (Finite a) (Finite b) = Finite $ a Prelude.++ b<br>infixr 5 ++<br><br>map = fmap</font><br><br><br>/J<br><br>2010/10/13 Eugene Kirpichov &lt;<a href="mailto:ekirpichov@gmail.com">ekirpichov@gmail.com</a>&gt;:<br>&gt; Well, it&#39;s easy to make it so that lists are either finite or bottom,<br>
&gt; but it&#39;s not so easy to make infinite lists fail to typecheck...<br>&gt; That&#39;s what I&#39;m wondering about.<br>&gt;<br>&gt; 2010/10/13 Miguel Mitrofanov &lt;<a href="mailto:miguelimo38@yandex.ru">miguelimo38@yandex.ru</a>&gt;:<br>
&gt;&gt; šhdList :: List a n -&gt; Maybe a<br>&gt;&gt; hdList Nil = Nothing<br>&gt;&gt; hdList (Cons a _) = Just a<br>&gt;&gt;<br>&gt;&gt; hd :: FiniteList a -&gt; Maybe a<br>&gt;&gt; hd (FL as) = hdList as<br>&gt;&gt;<br>
&gt;&gt; *Finite&gt; hd ones<br>&gt;&gt;<br>&gt;&gt; this hangs, so, my guess is that ones = _|_<br>&gt;&gt;<br>&gt;&gt;<br>&gt;&gt; 13.10.2010 12:13, Eugene Kirpichov ĐÉŰĹÔ:<br>&gt;&gt;&gt;<br>&gt;&gt;&gt; {-# LANGUAGE ExistentialQuantification, GADTs, EmptyDataDecls #-}<br>
&gt;&gt;&gt; module Finite where<br>&gt;&gt;&gt;<br>&gt;&gt;&gt; data Zero<br>&gt;&gt;&gt; data Succ a<br>&gt;&gt;&gt;<br>&gt;&gt;&gt; class Finite a where<br>&gt;&gt;&gt;<br>&gt;&gt;&gt; instance Finite Zero<br>&gt;&gt;&gt; instance (Finite a) =&gt; šFinite (Succ a)<br>
&gt;&gt;&gt;<br>&gt;&gt;&gt; data List a n where<br>&gt;&gt;&gt; š Nil :: List a Zero<br>&gt;&gt;&gt; š Cons :: (Finite n) =&gt; ša -&gt; šList a n -&gt; šList a (Succ n)<br>&gt;&gt;&gt;<br>&gt;&gt;&gt; data FiniteList a where<br>
&gt;&gt;&gt; š FL :: (Finite n) =&gt; šList a n -&gt; šFiniteList a<br>&gt;&gt;&gt;<br>&gt;&gt;&gt; nil :: FiniteList a<br>&gt;&gt;&gt; nil = FL Nil<br>&gt;&gt;&gt;<br>&gt;&gt;&gt; cons :: a -&gt; šFiniteList a -&gt; šFiniteList a<br>
&gt;&gt;&gt; cons a (FL x) = FL (Cons a x)<br>&gt;&gt;&gt;<br>&gt;&gt;&gt; list123 = cons 1 (cons 2 (cons 3 nil))<br>&gt;&gt;&gt;<br>&gt;&gt;&gt; ones = cons 1 ones -- typechecks ok<br>&gt;&gt;<br>&gt;&gt; _______________________________________________<br>
&gt;&gt; Haskell-Cafe mailing list<br>&gt;&gt; <a href="mailto:Haskell-Cafe@haskell.org">Haskell-Cafe@haskell.org</a><br>&gt;&gt; <a href="http://www.haskell.org/mailman/listinfo/haskell-cafe">http://www.haskell.org/mailman/listinfo/haskell-cafe</a><br>
&gt;&gt;<br>&gt;<br>&gt;<br>&gt;<br>&gt; --<br>&gt; Eugene Kirpichov<br>&gt; Senior Software Engineer,<br>&gt; Grid Dynamics <a href="http://www.griddynamics.com/">http://www.griddynamics.com/</a><br>&gt; _______________________________________________<br>
&gt; Haskell-Cafe mailing list<br>&gt; <a href="mailto:Haskell-Cafe@haskell.org">Haskell-Cafe@haskell.org</a><br>&gt; <a href="http://www.haskell.org/mailman/listinfo/haskell-cafe">http://www.haskell.org/mailman/listinfo/haskell-cafe</a><br>
&gt;<br><br></div>