Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why cannot one define := in GHC?

Tags:

haskell

Why cannot one define operator := in GHC? Can this limitation be eliminated in future releases?

Here is output:

[1 of 1] Compiling Images           ( Images.hs, interpreted )

Images.hs:19:1:
    Invalid type signature: (:=) :: HasSetter s => s a -> a -> IO ()
    Should be of form <variable> :: <type>
like image 803
danbst Avatar asked Jan 12 '23 06:01

danbst


1 Answers

Constructors vs functions

Constructors make new data types out of old data. Let's roll our own list:

data List a = Empty | Cons a (List a)

myList = Const 1 (Cons 2 Empty) -- 1:2:[] =[1,2]

uncons x' (Cons x xs) = if x == x' then xs else Cons x xs

Here, Cons :: a -> List a is a special function that takes an element and a list and makes a longer list.

It's important that there's a difference between constructor functions and ordinary functions, so that the compiler knows which one is valid in a pattern match:

headM (Cons x xs) = Just x
headM Empty = Nothing

That makes sense, but this doesn't:

previousHead (uncons x xs) = Just x
previousHead xs = Nothing

because how can the computer know which element you removed or whether you did remove one?

Infix Constructors and functions

Sometimes, as with lists, it's helpful to have a constructor work infix, so we actually have the equivalent of

data [a] = [] | a:[a]

so we can write lists like 1:2:[].

Infix functions need to be separate from identifiers so we can write x:xs unambiguously without spaces, so infix functions (including infix constructors like : have to consist entirely of symbols, not letters.

The compiler still needs to be able to tell constructors apart from ordinary functions when they're infix, so we need the equivalent of the rule that constructors start with a capital. The language designers designated : as the only capital symbol, so infix constructors have to start with it, and ordinary functions can't.

What you can do with :=

You can use := as a constructor, so you could define

data Assignment a = Variable := Expression a

But if you want to call an ordinary function :=, you can't, because : isn't allowed at the front as it counts as the capital symbol, you'd have to start with something else, for (simple but pointless) example:

(.:=) :: Maybe a -> a -> Maybe a
Nothing .:= x   = Just x
Just y  .:= x   = Just x
like image 175
not my job Avatar answered Jan 21 '23 13:01

not my job