Does `('a':_)` represent a tuple or a list? - list

A function that decides if a list begins with the letter ’a’ can be defined as follows:
test :: [Char] -> Bool
test ['a',_] = True
test _ = False
or
test :: [Char] -> Bool
test ('a':_) = True
test _ = False
Why does the first use [], while the second uses ()?
Does the second use ('a':_) to represent a tuple or a list?
If a tuple, doesn't test's argument have a list type [Char]?
If a list, doesn't () represent a tuple and how can it represent a list?

Does the second use ('a':_) to represent a tuple or a list?
A list.
If a list, doesn't () represent a tuple and how can it represent a list?
No, this is the unit type [wiki]. It is not a tuple, nor a list. Sometimes, as the Wikipedia article says, it is interpreted as an 0-tuple. It is defined in GHC.Tuple as well.
Why does the first use [], while the second uses ()?
The two are not equivalent. The former one matches a list with exactly two elements where the first element is an 'a', whereas the latter matches a list with at least one element where the first element is an 'a'. But the latter can match a list with one element, three elements, etc. whereas the former can only match lists with exactly two elements.
Background
(:) is a data constructor of a list. Indeed:
Prelude> :i (:)
data [] a = ... | a : [a] -- Defined in ‘GHC.Types’
infixr 5 :
The ('a': _) is just a nicer form of ((:) 'a' _). We here thus use one of the list data constructors.
The ['a', _] is syntactical sugar for (:) 'a' ((:) _ []), so here we match a list that starts with an 'a' and where the tail is a list with as head a value we do not care about and its tail the empty list data constructor.

Haskell's list notation is just syntactic sugar for "cons"ing elements on to the empty list (that is, using the : operator).
In other words,
[x,y,z]
is syntactic sugar for
x:(y:(z:[]))
(although this form would more normally be written as x:y:z:[] without the parentheses, since : is right-associative).
So, in the example you quote, ('a':_) represents any list whose first element is 'a', while ['a',_] is sugar for (a:(_:[])) which is a list of length exactly 2, whose first element is a.
Note that tuples are something else entirely, being denoted by a sequence of values in parentheses separated by commas.

In Haskell there are data constructors that are symbols, some examples that may confuse you:
() :: ()
that's the type unit with its constructor () and its value ()
then there is:
(,) :: a -> b -> (a,b)
(,) is the constructor for tuples, for example (1,"b") that can be (1,) “b” or (,) 1 “b”
finally your case:
(:) :: a -> [a] -> [a]
for example, 1:[] that can be [1] or (:) 1 []

Related

OCaml why does an empty array have polymorphic type?

OCaml arrays are mutable. For most mutable types, even an "empty" value does not have polymorphic type.
For example,
# ref None;;
- : '_a option ref = {contents = None}
# Hashtbl.create 0;;
- : ('_a, '_b) Hashtbl.t = <abstr>
However, an empty array does have a polymorphic type
# [||];;
- : 'a array = [||]
This seems like it should be impossible since arrays are mutable.
It happens to work out in this case because the length of an array can't change and thus there's no opportunity to break soundness.
Are arrays special-cased in the type system to allow this?
The answer is simple -- an empty array has the polymorphic type because it is a constant. Is it special-cased? Well, sort of, mostly because an array is a built-in type, that is not represented as an ADT, so yes, in the typecore.ml in the is_nonexpansive function, there is a case for the array
| Texp_array [] -> true
However, this is not a special case, it is just a matter of inferring which syntactic expressions form constants.
Note, in general, the relaxed value restriction allows generalization of expressions that are non-expansive (not just syntactic constants as in classical value restriction). Where non-expansive expression is either a expression in the normal form (i.e., a constant) or an expression whose computation wouldn't have any observable side effects. In our case, [||] is a perfect constant.
The OCaml value restriction is even more relaxed than that, as it allows the generalization of some expansive expressions, in case if type variables have positive variance. But this is a completely different story.
Also,ref None is not an empty value. A ref value by itself, is just a record with one mutable field, type 'a ref = {mutable contents : 'a} so it can never be empty. The fact that it contains an immutable value (or references the immutable value, if you like) doesn't make it either empty or polymorphic. The same as [|None|] that is also non-empty. It is a singleton. Besides, the latter has the weak polymorphic type.
I don't believe so. Similar situations arise with user-defined data types, and the behaviour is the same.
As an example, consider:
type 'a t = Empty | One of { mutable contents : 'a }
As with an array, an 'a t is mutable. However, the Empty constructor can be used in a polymorphic way just like an empty array:
# let n = Empty in n, n;;
- : 'a t * 'b t = (Empty, Empty)
# let o = One {contents = None};;
val o : '_weak1 option t = One {contents = None}
This works even when there is a value of type 'a present, so long as it is not in a nonvariant position:
type 'a t = NonMut of 'a | Mut of { mutable contents : 'a }
# let n = NonMut None in n, n;;
- : 'a option t * 'b option t = (NonMut None, NonMut None)
Note that the argument of 'a t is still nonvariant and you will lose polymorphism when hiding the constructor inside a function or module (roughly because variance will be inferred from arguments of the type constructor).
# (fun () -> Empty) ();;
- : '_weak1 t = Empty
Compare with the empty list:
# (fun () -> []) ();;
- : 'a list = []

tagged type / List - F# Language design [duplicate]

I'm reading Expert F# 4.0 and at some point (p.93) the following syntax is introduced for list:
type 'T list =
| ([])
| (::) of 'T * 'T list
Although I understand conceptually what's going on here, I do not understand the syntax. Apparently you can put [] or :: between parentheses and they mean something special.
Other symbols aren't allowed, for example (++) or (||). So what's going on here?
And another thing is the 'operator' nature of (::). Suppose I have the following (weird) type:
type 'T X =
| None
| Some of 'T * 'T X
| (::) of 'T * 'T X
Now I can say:
let x: X<string> = Some ("", None)
but these aren't allowed:
let x: X<string> = :: ("", None)
let x: X<string> = (::) ("", None)
So (::) is actually something completely different than Some, although both are cases in a discriminated union.
Theoretically, F# spec (see section 8.5) says that union case identifiers must be alphanumeric sequences starting with an upper-case letter.
However, this way of defining list cons is an ML idiomatic thing. There would be riots in the streets if we were forced to write Cons (x, Cons(y, Cons (z, Empty))) instead of x :: y :: z :: [].
So an exception was made for just these two identifiers - ([]) and (::). You can use these, but only these two. Besides these two, only capitalized alphanumeric names are allowed.
However, you can define free-standing functions with these funny names:
let (++) a b = a * b
These functions are usually called "operators" and can be called via infix notation:
let x = 5 ++ 6 // x = 30
As opposed to regular functions that only support prefix notation - i.e. f 5 6.
There is a separate quite intricate set of rules about which characters are allowed in operators, which can be only unary, which can be only binary, which can be both, and how they define the resulting operator precedence. See section 4.1 of the spec or here for full reference.

SML: Error: operator and operand don't agree [tycon mismatch]

I'm trying to write a SML function that has two argument, the first is an
int and the second is a list of lists. The objective is to insert the first argument onto the front of every list in the second arguemnt. For example, append_to_front(1,[[3,4],[6,8],[]]) should return [[1,3,4],[1,6,8],[1]].
I have the code:
fun append_to_front(a:int, L:int list list) =
if L = []
then []
else a::hd(L)::append_to_front(a, tl(L));
and I get the error message: Error: operator and operand don't agree [tycon mismatch]. Why?
The cons operator :: has type 'a * 'a list -> 'a list, that is, it requires an element on the left and a list on the right. Moreover, it is right-associative, i.e., a::b::c = a::(b::c).
In your case, a has type int, b and c both have type int list. Consequently, the second use of :: isn't well-typed, because it has a list on both sides. Use list concatenation # in that place instead.

Is list a monad and comonad?

The list monad is given here. Also see Spivak's paper here. So list is a monad. Is it a comonad? How would you prove that?
The list type constructor a ↦ μ L. 1 + a * L doesn't admit a comonad structure. Recall that if it were a comonad, we'd have (using the names from Haskell's Functor and Comonad typeclasses)
fmap :: ∀ a b. (a → b) → [a] → [b]
extract :: ∀ a. [a] → a
duplicate :: ∀ a. [a] → [[a]]
However, even without going into any required laws, extract cannot be implemented, since its input could be the empty list, giving no way to come up with an a.
The nonempty list type constructor a ↦ μ NE. a + a * NE does admit a comonad structure, with extract returning the first element, and duplicate mapping [x, y, ..., z] to [[x], [x, y], ..., [x, y, ..., z]] (note that each of them are non-empty by construction).

Is undefined a partial list in Haskell?

Is undefined a partial list in Haskell?
I know that [1,2:undefined] is partial but what about about undefined alone?
undefined is a function that causes an error if you try to evaluate it. (However, if you don't try to evaluate it, it does no harm.) Let's examine the type signature for undefined:
ghci> :t undefined
undefined :: a
That a is a type variable, and since there are no constraints identified in the type signature (type constraints appear between :: and => symbols), a can be of any type.
I'm not sure if you really wanted a : in your example.
[1,2,undefined] is a list of integers, so the type of undefined in this expression is also an integer.
(1:2:undefined) is also a list of integers, but : takes a list as its second argument, so the type of undefined in this expression is a list of integer.
I don't think [1,2:undefined] makes sense. 1 is an integer, but 2:undefined is a list of integers. You can't have a list with elements of different types.
EDIT:
undefined isn't really a partial list*, it's just a single value (which could be of any type, including a list). For example, [1,2,undefined] is a list with three elements. The first element is 1, the second element is 2, and the third element can't be evaluated -- but it is an integer.
*However, a list with undefined as the last element could be used to represent some sort of "partial list", insofar as you can't evaluate that element. (I think that's what #Daniel means). However, if there are elements before or after it, you could evaluate them. For example:
ghci> last [1,2,undefined,4]
4
EDIT #2:
Another example might help. Here I've created a list with four elements, one of which (c) is undefined. When I query ghci to find out the type of c, I see that it's just a single integer, not a list.
ghci> let (a:b:c:d) = [1,2,undefined,4]
ghci> :type c
c :: Integer
Your question is not very clear as the comments pointed out but let's make some assumptions. First you probably meant to write 1:2:undefined as your example of a partial list.
> let p1 = 1:2:undefined
> :t p1
p1 :: [Integer]
So p1 has two elements and the rest is undefined which makes it a partial list in some sense. Following this definition this type-checks:
> let p2 = undefined :: [Int]
> :t p2
p2 :: [Int]
It has 0 elements and the rest is undefined. We can call it an empty partial list.
Another way to think about it is that p1 is the same as [1,2] ++ undefined and p2 is [] ++ undefined.
I have found answer for my question in Introduction to Functional Programing. | aka undefined is a Partial List (base of induction for them)