Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What are nonlinear patterns

I am reading the paper about the servant-api DSL (see pdf here)

Quoting from Section 5.2 Type safe Links (emphasize added by me)

type family ElSymbol e (s :: Symbol) a :: Bool where
ElSymbol (s :> e) s a = Elem e a
ElSymbol e s a = False

Note that type families in GHC – unlike normal function definitions – allow non-linear patterns, and the double occurrence of s on the left hand side of the first case implies that both symbols must be equal.

What are non-linear patterns in haskell?

The fact that both occurrences of s need to be equal, is clear this is a consequence of the ScopedTypeVariables-pragma.

I know linear/non-linear functions only from the context of mathematics where y = kx + d is a (1-dimensional) linear function and something like y = x² sin(x) would be an example for a non-linear function.

I guess the non-linearity comes from the type constructor (Quoting from Section 3.3 Types are first-class citizens)

data (item :: k) :> api
infixr 9 :>

but I cannot quite understand what makes this non-linear, and what would be an example of a linear constructor, if my guess is correct, that the constructor is introducing the non-linearity.

like image 506
epsilonhalbe Avatar asked Mar 09 '16 12:03

epsilonhalbe


1 Answers

A linear pattern is a patter where each variable appears at most one.

A non-linear pattern allows reusing the same variable name implying that all the values matched by it must be equal.

What the documentation is saying is that non linear patterns are accepted in type families definitions while they are not in normal function definitions:

Prelude> let f x x = x

<interactive>:2:7:
    Conflicting definitions for ‘x’
    Bound at: <interactive>:2:7
              <interactive>:2:9
    In an equation for ‘f’

There's nothing "deep" in this. There are other languages which allow "non linear" patterns in function definitions (e.g. Curry).

So: no, type constructors have nothing to do with linearity/non linerity. Is just how you use variables in the pattern matching.


As to why Haskell doesn't have non linear patterns for function definitions: there are cons. For example what should \x x -> x mean? \x -> \x -> x? Or \x y | x == y -> x?

Also f x x = 1 would not be a total function. There's an hidden guard, and thus f [1..] [1..] would loop forever instead of simply returning 1.


As has been pointed out in the comments, the linear term may come from linear logic. This logic has a "resource interpretation" where, fundamentally, implication "consumes" its antecedent in order to produce the consequent.

In its sequent calculus you cannot reuse an hypothesis multiple times as you do in classical logic. This is akin to linear patterns: you cannot reuse the same variable multiple times. Follow-up question: why is linear logic called linear logic? No idea.

like image 176
Bakuriu Avatar answered Oct 02 '22 14:10

Bakuriu