Something that <i>bugs</i> me in Haskell, and which Mars inherits as it is mostly the same semantics - you've taken the effort to create a good type system with optional types and type checking, only to decide to not actually use them for some common operations you're performing in the language (namely, head/tail).<p><pre><code> ?> Nil.head
Runtime Error: List instance has no field 'head'
</code></pre>
Such runtime errors could easily be avoided by making head/tail return Maybe, and using Nothing in the case of Nil. This hardly complicates code, but it provides the correct behavior, particularly when it comes to doing "records" properly. The Mars docs give an example of how I consider copying Haskell's semantics directly without improving them leads to flawed code.<p><pre><code> type Foo:
X(u :: Num, v :: Num)
Y(v :: Num)
</code></pre>
There's nothing wrong with `v` here, as it is total, but you can easily introduce a runtime error by using `u` incorrectly.<p><pre><code> ?> x = Y(1)
?> x.u
Runtime Error: Foo instance has no field 'u'
</code></pre>
This is why using records in combination with sum types in Haskell is widely considered a bad idea. It's a misfeature as far as I'm concerned. If given the chance to redo Haskell's awful record system, I'd fix it.<p>The problem can be trivially avoided by making `u` return `Maybe Num` in this example, where it returns Nothing for Y and `Just 1` for X. Ideally, the compiler should check if field names are total over the constructors - if not, it should automatically return an optional type. If the fields are total there's no need. I doubt there would be any noticeable performance cost to moving the error to compile time - particularly because you don't actually need to use it in internal implementations of map/fold and such - you could have an internal function which mimics the current behavior, but don't expose it from the module.