Is undefined a partial list in Haskell? - list

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)

Related

Maybe and Either monads, short-circuiting, and performance

Functional Programming in C++, at page 214, with reference to an expected<T,E> monad which is the same as Haskell's Either, reads
[...] as soon as any of the functions you're binding to returns an error, the execution will stop and return that error to the caller.
Then, in a caption just below, it reads
If you call mbind [equivalent to Haskell's >>=] on an expected that contains an error,, mbind won't even invoke the transformation function; it will just forward that error to the result.
which seems to "adjust" what was written earlier. (I'm pretty sure that either LYAH or RWH underlines somewhere that there's no short-circuiting; if you remember where, please, remind me about it.)
Indeed, my understanding, from Haskell, is that in a chain of monadic bindings, all of the bindings happen for real; then what they do with the function passed to them as a second argument, is up to the specific monad.
In the case of Maybe and Either, when the bindings are passed a Nothing or Left x argument, then the second argument is ignored.
Still, in these specific two cases, I wonder if there's a performance penalty in doing something like this
justPlus1 = Just . (+1)
turnToNothing = const Nothing
Just 3 >>= turnToNothing >>= justPlus1
>>= justPlus1
>>= justPlus1
>>= justPlus1
>>= justPlus1
as in these cases the chain can't really do anything other than what it does, given that
Nothing >>= _ = Nothing
Left l >>= _ = Left l
Consider the following expression:
result :: Maybe Int
result = x >>= f >>= g >>= h
In that expression, of course, x :: Maybe a for some a, and each of f, g, and h are functions, with h returning Maybe Int but the intermediate types of the pipeline could be anything wrapped in a Maybe. Perhaps f :: String -> Maybe String, g :: String -> Maybe Char, h :: Char -> Maybe Int.
Let's make the associativity explicit as well:
result :: Maybe Int
result = ((x >>= f) >>= g) >>= h
To evaluate the expression, each bind (>>=) must in fact be called, but not necessarily the functions f, g, or h. Ultimately the bind to h needs to inspect its left-hand argument to decide whether it is Nothing or Just something; in order to determine that we need to call the bind to g, and to decide that we need to call the bind to f, which must at least look at x. But once any one of these binds produces Nothing, we pay only for checking Nothing at each step (very cheap), and not for calling the (possibly expensive) downstream functions.
Suppose that x = Nothing. Then the bind to f inspects that, sees Nothing, and doesn't bother to call f at all. But we still need to bind the result of that in order to know if it's Nothing or not. And this continues down the chain until finally we get result = Nothing, having called >>= three times but none of the functions f, g, or h.
Either behaves similarly with Left values, and other monads may have different behaviors. A list may call each function one time, many times, or no times; the tuple monad calls each function exactly once, having no short-circuiting or other multiplicity features.
You seem to have a misunderstanding of how the Monad instances for these types work in Haskell. You say:
Indeed, my understanding, from Haskell, is that in a chain of monadic functions, all of the functions are called,
But this demonstrably isn't the case. Indeed any time you compute
Nothing >>= f
where f is any function of type a -> Maybe b, then it is computed according to the implementation of >>= for the Maybe monad, which is:
Just x >>= f = f x
Nothing >>= f = Nothing
So f will indeed be called in the Just case, but not in the Nothing case. So we see that there is indeed "short circuiting". Indeed, since Haskell is lazy, every function "short circuits" by default - nothing is ever computed unless it's needed to produce a result.
It's an interesting question to ask about performance - and not a question I personally know how to answer. Certainly, as I just explained, none of the following functions in the chain will be evaluated once a Nothing is encountered - but performing the pattern matching to see this is unlikely to be free. Perhaps the compiler is able to optimise this away, by reasoning that it can abandon the entire calculation once it hits a Nothing. But I'm not sure.

Does `('a':_)` represent a tuple or a 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 []

SML Operator and operand don't agree in foldr

I'm working on an assignment where I have to write a function to get the length of a list. This is a trivial task, but I've come across something that I don't understand.
My simple code
val len = foldr (fn(_, y) => y + 1) 0
produces this warning
Warning: type vars not generalized because of
value restriction are instantiated to dummy types (X1,X2,...)
and when I try to run it in the REPL, I get this:
len [1, 2, 3, 4];
stdIn:18.1-18.17 Error: operator and operand don't agree [overload conflict]
operator domain: ?.X1 list operand:
[int ty] list in expression:
len (1 :: 2 :: 3 :: <exp> :: <exp>)
I don't understand why this doesn't work. I do know some functional programming principles, and this should work, since its very simple partial application.
Of course I can make it work without partial application, like this
fun len xs = foldr (fn(_, y) => y + 1) 0 xs
but I would like to understand why the first version doesn't work.
This is an instance of the value restriction rule application:
In short, the value restriction says that generalization can only occur if the right-hand side of an expression is syntactically a value.
Syntactically,
foldr (fn(_, y) => y + 1) 0
is not a value, it's a function application, that's why it hasn't been assigned a polymorphic type. It has been instantiated with a dummy type, which has a very limited use, e.g. this works:
len []
but in most cases len defined as val is useless.
This restriction exists to guarantee type safety in the presence of variable assignment (via references). More details can be found in the linked page.

Multipying int64 types in OCAML

I am attempting to multiply two int types in OCAML and I am not sure on what I might be doing wrong
let prime = Int64.of_string("0x100000002b2") in
let temp = ref prime in
hash := Int64.mul(!temp,prime);
I get the error
Error: This expression has type 'a * 'b
but an expression was expected of type int64
Any suggestions on how I can fix this ?
Update:
I got reference to this method from here
I am curious what this means
val mul : int64 -> int64 -> int64
Multiplication.
How do we know how many parameters this method takes ?
Function parameters in OCaml are (in the usual idiom) placed after the name of the function, with no parentheses and no comma.
# Int64.mul 8L 9L;;
- : int64 = 72L
Commas are used to create tuples, but Int64.mul doesn't accept a tuple. It accepts two separate arguments as above. (In FP parlance, it's a curried function.)
(It might be worth working through a short tutorial on OCaml. You seem to be assuming it's like traditional C family languages, but it's rather different.)
Update
The type x -> y is the type of a function that accepts a parameter of type x and returns a value of type y. The type x -> y -> z is the type of a (curried) function that takes two parameters of types x and y and returns a value of type z. (This is a somewhat simplified way of looking at things, but is close enough to get started with.)
So the function mul that you cite takes two parameters of type int64 and returns a value of type int64.
(I repeat my advice about an OCaml tutorial. It's really worth learning about the OCaml type system before getting too deep into coding.)

OCaml type of the plus operator

Why is the type of a plus ( + ) considered to be int -> int -> int as opposed to (int * int) -> int? To me, the second makes sense because it "accepts" a 2-tuple (the addends) and returns a single int (their sum).
Thank you!
You can make a language where (+) has the type (int * int) -> int. In fact, SML works exactly this way. It just affects the meaning of infix operators. However OCaml conventions strongly favor the use of curried functions (of the type a -> b -> c) rather than uncurried ones. One nice result is that you can partially apply them. For example ((+) 7) is a meaningful expression of type int -> int. I find this notation useful quite often.
This might seem a little unhelpful, but it's because the function takes two arguments.
When a function takes a tuple, it is in effect taking a single argument.
Because (+) is an inline function, taking a single argument would not be useful, as it would look like + (1,2) as opposed to 1 + 2.