Related
I have been going through the Seven Languages in Seven Weeks book and I'm working with Haskell.
I am struggling with the problem:
Write a sort that takes a list and a function that compares its two arguments and then returns a sorted list.
I searched online for help and found a solution but I can't even get the solution to run because of an expected to actual type error.
Here is the code I've been trying:
module Main where
import Data.List
sortList :: (Ord a) => (a -> a -> Ordering) -> [a] -> [a]
sortList comparator list = sortBy comparator list
Here is the error:
*Main> sortList [5,4,2,7,8,1]
<interactive>:1:10:
Couldn't match expected type `a -> a -> Ordering'
with actual type `[t]'
In the first argument of `sortList', namely `[5, 4, 2, 7, ....]'
In the expression: sortList [5, 4, 2, 7, ....]
In an equation for `it': it = sortList [5, 4, 2, ....]
My Thoughts and Attempts:
Maybe I am calling the function wrong? I am fairly new to Haskell. II tried doing many searches as well. All I could conclude is that somewhere the types aren't matching up. I suppose explanation and guidance for the script would be very helpful to me.
Your function signature says:
"sortList is a function that takes:"
function (a -> a -> Ordering) that take two elements of type 'a' and returns an 'Ordering' [this is your comparator]
List of items 'a' ([a]) that you are passing it
Returns a list of items 'a' ([a])
Try call them in this way:
sortList compare [3,2,1]
For more read here:
https://hackage.haskell.org/package/base-4.8.2.0/docs/Data-Ord.html
and here:
http://zvon.org/other/haskell/Outputprelude/compare_f.html
You are calling the function wrong, you need to pass it a comparator function. You just pass a list to the function.
In working through a solution to the 8 Queens problem, a person used the following line of code:
sameDiag try qs = any (\(colDist,q) -> abs (try - q) == colDist) $ zip [1..] qs
try is an an item; qs is a list of the same items.
Can someone explain how colDist and q in the lambda function get bound to anything?
How did try and q used in the body of lambda function find their way into the same scope?
To the degree this is a Haskell idiom, what problem does this design approach help solve?
The function any is a higher-order function that takes 2 arguments:
the 1st argument is of type a -> Bool, i.e. a function from a to Bool
the 2nd argument is of type [a], i.e. a list of items of type a;
i.e. the 1st argument is a function that takes any element from the list passed as the 2nd argument, and returns a Bool based on that element. (well it can take any values of type a, not just the ones in that list, but it's quite obviously certain that any won't be invoking it with some arbitrary values of a but the ones from the list.)
You can then simplify thinking about the original snippet by doing a slight refactoring:
sameDiag :: Int -> [Int] -> Bool
sameDiag try qs = any f xs
where
xs = zip [1..] qs
f = (\(colDist, q) -> abs (try - q) == colDist)
which can be transformed into
sameDiag :: Int -> [Int] -> Bool
sameDiag try qs = any f xs
where
xs = zip [1..] qs
f (colDist, q) = abs (try - q) == colDist)
which in turn can be transformed into
sameDiag :: Int -> [Int] -> Bool
sameDiag try qs = any f xs
where
xs = zip [1..] qs
f pair = abs (try - q) == colDist) where (colDist, q) = pair
(Note that sameDiag could also have a more general type Integral a => a -> [a] -> Bool rather than the current monomorphic one)
— so how does the pair in f pair = ... get bound to a value? well, simple: it's just a function; whoever calls it must pass along a value for the pair argument. — when calling any with the first argument set to f, it's the invocation of the function any who's doing the calling of f, with individual elements of the list xs passed in as values of the argument pair.
and, since the contents of xs is a list of pairs, it's OK to pass an individual pair from this list to f as f expects it to be just that.
EDIT: a further explanation of any to address the asker's comment:
Is this a fair synthesis? This approach to designing a higher-order function allows the invoking code to change how f behaves AND invoke the higher-order function with a list that requires additional processing prior to being used to invoke f for every element in the list. Encapsulating the list processing (in this case with zip) seems the right thing to do, but is the intent of this additional processing really clear in the original one-liner above?
There's really no additional processing done by any prior to invoking f. There is just very minimalistic bookkeeping in addition to simply iterating through the passed in list xs: invoking f on the elements during the iteration, and immediately breaking the iteration and returning True the first time f returns True for any list element.
Most of the behavior of any is "implicit" though in that it's taken care of by Haskell's lazy evaluation, basic language semantics as well as existing functions, which any is composed of (well at least my version of it below, any' — I haven't taken a look at the built-in Prelude version of any yet but I'm sure it's not much different; just probably more heavily optimised).
In fact, any is simple it's almost trivial to re-implement it with a one liner on a GHCi prompt:
Prelude> let any' f xs = or (map f xs)
let's see now what GHC computes as its type:
Prelude> :t any'
any' :: (a -> Bool) -> [a] -> Bool
— same as the built-in any. So let's give it some trial runs:
Prelude> any' odd [1, 2, 3] -- any odd values in the list?
True
Prelude> any' even [1, 3] -- any even ones?
False
Prelude> let adult = (>=18)
Prelude> any' adult [17, 17, 16, 15, 17, 18]
— see how you can sometimes write code that almost looks like English with higher-order functions?
zip :: [a] -> [b] -> [(a,b)] takes two lists and joins them into pairs, dropping any remaining at the end.
any :: (a -> Bool) -> [a] -> Bool takes a function and a list of as and then returns True if any of the values returned true or not.
So colDist and q are the first and second elements of the pairs in the list made by zip [1..] qs, and they are bound when they are applied to the pair by any.
q is only bound within the body of the lambda function - this is the same as with lambda calculus. Since try was bound before in the function definition, it is still available in this inner scope. If you think of lambda calculus, the term \x.\y.x+y makes sense, despite the x and the y being bound at different times.
As for the design approach, this approach is much cleaner than trying to iterate or recurse through the list manually. It seems quite clear in its intentions to me (with respect to the larger codebase it comes from).
In several programming languages (including JavaScript, Python, and Ruby), it's possible to place a list inside itself, which can be useful when using lists to represent infinitely-detailed fractals. However, I tried doing this in Haskell, and it did not work as I expected:
--aList!!0!!0!!1 should be 1, since aList is recursively defined: the first element of aList is aList.
main = putStrLn $ show $ aList!!0!!0!!1
aList = [aList, 1]
Instead of printing 1, the program produced this compiler error:
[1 of 1] Compiling Main ( prog.hs, prog.o )
prog.hs:3:12:
Occurs check: cannot construct the infinite type: t0 = [t0]
In the expression: aList
In the expression: [aList, 1]
In an equation for `aList': aList = [aList, 1]
Is it possible to put an list inside itself in Haskell, as I'm attempting to do here?
No, you can't. First off, there's a slight terminological confusion: what you have there are lists, not arrays (which Haskell also has) , although the point stands either way. So then, as with all things Haskell, you must ask yourself: what would the type of aList = [aList, 1] be?
Let's consider the simpler case of aList = [aList]. We know that aList must be a list of something, so aList :: [α] for some type α. What's α? As the type of the list elements, we know that α must be the type of aList; that is, α ~ [α], where ~ represents type equality. So α ~ [α] ~ [[α]] ~ [[[α]]] ~ ⋯ ~ [⋯[α]⋯] ~ ⋯. This is, indeed, an infinite type, and Haskell forbids such things.
In the case of the value aList = [aList, 1], you also have the restriction that 1 :: α, but all that that lets us conclude is that there must be a Num α constraint (Num α => [⋯[α]⋯]), which doesn't change anything.
The obvious next three questions are:
Why do Haskell lists only contain one type of element?
Why does Haskell forbid infinite types?
What can I do about this?
Let's tackle those in order.
Number one: Why do Haskell lists only contain one type of element? This is because of Haskell's type system. Suppose you have a list of values of different types: [False,1,2.0,'c']. What's the type of the function someElement n = [False,1,2.0,'c'] !! n? There isn't one, because you couldn't know what type you'd get back. So what could you do with that value, anyway? You don't know anything about it, after all!
Number two: Why does Haskell forbid infinite types? The problem with infinite types is that they don't add many capabilities (you can always wrap them in a new type; see below), and they make some genuine bugs type-check. For example, in the question "Why does this Haskell code produce the ‘infinite type’ error?", the non-existence of infinite types precluded a buggy implementation of intersperse (and would have even without the explicit type signature).
Number three: What can I do about this? If you want to fake an infinite type in Haskell, you must use a recursive data type. The data type prevents the type from having a truly infinite expansion, and the explicitness avoids the accidental bugs mentioned above. So we can define a newtype for an infinitely nested list as follows:
Prelude> newtype INL a = MkINL [INL a] deriving Show
Prelude> let aList = MkINL [aList]
Prelude> :t aList
aList :: INL a
Prelude> aList
MkINL [MkINL [MkINL [MkINL ^CInterrupted.
This got us our infinitely-nested list that we wanted—printing it out is never going to terminate—but none of the types were infinite. (INL a is isomorphic to [INL a], but it's not equal to it. If you're curious about this, the difference is between isorecursive types (what Haskell has) and equirecursive types (which allow infinite types).)
But note that this type isn't very useful; the only lists it contains are either infinitely nested things like aList, or variously nested collections of the empty list. There's no way to get a base case of a value of type a into one of the lists:
Prelude> MkINL [()]
<interactive>:15:8:
Couldn't match expected type `INL a0' with actual type `()'
In the expression: ()
In the first argument of `MkINL', namely `[()]'
In the expression: MkINL [()]
So the list you want is an arbitrarily nested list. The 99 Haskell Problems has a question about these, which requires defining a new data type:
data NestedList a = Elem a | List [NestedList a]
Every element of NestedList a is either a plain value of type a, or a list of more NestedList as. (This is the same thing as an arbitrarily-branching tree which only stores data in its leaves.) Then you have
Prelude> data NestedList a = Elem a | List [NestedList a] deriving Show
Prelude> let aList = List [aList, Elem 1]
Prelude> :t aList
aList :: NestedList Integer
Prelude> aList
List [List [List [List ^CInterrupted.
You'll have to define your own lookup function now, and note that it will probably have type NestedList a -> Int -> Maybe (NestedList a)—the Maybe is for dealing with out-of-range integers, but the important part is that it can't just return an a. After all, aList ! 0 is not an integer!
Yes. If you want a value that contains itself, you'll need a type that contains itself. This is no problem; for example, you might like rose trees, defined roughly like this in Data.Tree:
data Tree a = Node a [Tree a]
Now we can write:
recursiveTree = Node 1 [recursiveTree]
This isn't possible with the list type in Haskell, since each element has to be of the same type, but you could create a data type to do it. I'm not exactly sure why you'd want to, though.
data Nested a
= Value a
| List [Nested a]
deriving (Eq, Show)
nested :: Nested Int
nested = List [nested, Value 1]
(!) :: Nested a -> Int -> Nested a
(!) (Value _) _ = undefined
(!) (List xs) n = xs !! n
main = print $ nested ! 0 ! 0 ! 1
This will print out Value 1, and this structure could be of some use, but I'd imagine it's pretty limited.
There were several answers from "yes you can" to "no you absolutely cannot". Well, both are right, because all of them address different aspects of your question.
One other way to add "array" to itself, is permit a list of anything.
{-# LANGUAGE ExistentialQuantification #-}
data T = forall a. T a
arr :: [T]
arr = [T arr, T 1]
So, this adds arr to itself, but you cannot do anything else with it, except prove it is a valid construct and compile it.
Since Haskell is strongly typed, accessing list elements gives you T, and you could extract the contained value. But what is the type of that value? It is "forall a. a" - can be any type, which in essence means there are no functions at all that can do anything with it, not even print, because that would require a function that can convert any type a to String. Note that this is not specific to Haskell - even in dynamic languages the problem exists; there is no way to figure out the type of arr !! 1, you only assume it is a Int. What makes Haskell different to that other language, is that it does not let you use the function unless you can explain the type of the expression.
Other examples here define inductive types, which is not exactly what you are asking about, but they show the tractable treatment of self-referencing.
And here is how you could actually make a sensible construct:
{-# LANGUAGE ExistentialQuantification #-}
data T = forall a. Show a => T a
instance Show T where -- this also makes Show [T],
-- because Show a => Show [a] is defined in standard library
show (T x) = show x
arr :: [T]
arr = [T arr, T 1]
main = print $ arr !! 1
Now the inner value wrapped by T is restricted to be any instance of Show ("implementation of Show interface" in OOP parlance), so you can at least print the contents of the list.
Note that earlier we could not include arr in itself only because there was nothing common between a and [a]. But the latter example is a valid construct once you can determine what's the common operation that all the elements in the list support. If you can define such a function for [T], then you can include arr in the list of itself - this function determines what's common between certain kinds of a and [a].
No. We could emulate:
data ValueRef a = Ref | Value a deriving Show
lref :: [ValueRef Int]
lref = [Value 2, Ref, Value 1]
getValue :: [ValueRef a] -> Int -> [ValueRef a]
getValue lref index = case lref !! index of
Ref -> lref
a -> [a]
and have results:
>getValue lref 0
[Value 2]
>getValue lref 1
[Value 2,Ref,Value 1]
Sure, we could reuse Maybe a instead of ValueRef a
I was just wondering if there is a possibility to create a function that returns an (hopefully infinite) list of numbers similar to this. [1, [2, [3, [4]]]].
The closest I got was this.
func list 0 = list
func list num = func newList (num-1)
where newList = list ++ [[num]]
This is used something like this.
func [] 3
Which returns this.
[[3],[2],[1]]
Now I know that this is not infinite nor is it in the correct order but I just wanted to show that I was at least attempting something before posting. :)
Thanks a bunch!
You cannot write such a function, because all elements of a list must have the same type. The list you want to create would not typecheck even in the case of just two elements:
Prelude> :t [1::Int,[2::Int]]
<interactive>:1:9:
Couldn't match expected type `Int' with actual type `[Int]'
In the expression: [2 :: Int]
In the expression: [1 :: Int, [2 :: Int]]
First element is a Int, second one a list of Int, hence typechecking fails.
Although you can express the result with tuples, e.g.
Prelude> :t (1::Int,(2::Int,(3::Int,4::Int)))
(1::Int,(2::Int,(3::Int,4::Int))) :: (Int, (Int, (Int, Int)))
You still cannot write the function, because the type of the result would change depending on the number of elements you wish to have. Let's call f the hypothetical function:
f 1 :: (Int)
f 2 :: (Int,(Int))
f 3 :: (Int,(Int,(Int)))
...
The type of f changes with the argument, so f cannot be written.
The key is to come up with the correct type.
If you want something like [1, [2, [3, [4]]]], then doing exactly that won't work, because all list elements must be the same type.
This makes sense, because when I grab an element out of the list, I need to know what type it is before I can do anything with it (this is sort of the whole point of types, they tell you what you can and can't do with a thing).
But since Haskell's type system is static, I need to know what type it is even without knowing which element of the list it is, because which list index I'm grabbing might not be known until the program runs. So I pretty much have to get the same type of thing whatever index I use.
However, it's possible to do something very much like what you want: you want a data type that might be an integer, or might be a list:
type IntegerOrList a = Either Integer [a]
If you're not familiar with the Either type, a value of Either l r can either be Left x for some x :: l, or Right y for some y :: r. So IntegerOrList a is a type whose values are either an integer or a list of something. So we can make a list of those things: the following is a value of type [IntegerOrList Bool]:
[Left 7, Left 4, Right [True, False], Left 8, Right [], Right [False]]
Okay, so that's one level of lists inside lists, but we can't put lists inside lists inside lists yet – the inner lists contain Bools, which can't be lists. If we instead had [IntegerOrList (IntegerOrList Bool)], we'd be able to have lists inside lists inside lists, but we'd still get no further. In our example, we had a list which contained values which were either integers or lists, and the lists were lists which contained values which were either integers or lists, and... what we really want is something like IntegerOrList (IntegerOrList (IntegerOrList ..., or more simply, something like:
type IntegerOrLists = Either Integer [IntegerOrLists]
But that's not allowed – type synonyms can't be recursive, because that would produce an infinitely large type, which is confusing for the poor compiler. However, proper data types can be recursive:
data IntegerOrLists = I Integer | L [IntegerOrLists]
Now you can build lists like these, mixing integers and lists of your type:
L [I 1, L [I 2, L [I 3, L [I 4]]]]
The key is that whether each item is an integer or a list has to be flagged by using the I or L constructors. Now each element of the list is of type IntegerOrLists, and we can distinguish which it is by looking at that constructor. So the typechecker is happy at last.
{-# LANGUAGE ExistentialQuantification #-}
class Foo a
instance Foo Int
instance Foo [a]
data F = forall a. Foo a => F a
test = F [F (1 :: Int), F [F (2 :: Int), F [F (3 :: Int), F [F (4 :: Int)]]]]
This example shows
That you can have such structures in Haskell, just use some gift wrapping
That these structures are practically useless (try to do something with it)
How can I best convert a list to a tuple in Haskell:
[1,2,3,4,5,6] -> (1,2,3,4,5,6)
In a general way, you can't. Each size of tuple is a distinct type, whereas lists of any length are a single type. Thus, there's no good way to write a function that takes a list and returns a tuple of the same length--it wouldn't have a well-defined return type.
For instance, you could have functions like:
tuplify2 :: [a] -> (a,a)
tuplify2 [x,y] = (x,y)
tuplify3 :: [a] -> (a,a,a)
tuplify3 [x,y,z] = (x,y,z)
...but not one that does the job of both.
You can write a generic version using various kinds of meta-programming, but you'd rarely want to.
Note that the same problem applies to other things, such as writing class instances for various tuples--take a look at the source code for Data.Tuple from the standard libraries!
Template Haskell is as close as you can get due to type checking if you want to extract a variable number of elements, since (a,b) and (a,b,c) have different types.
{-# LANGUAGE TemplateHaskell #-}
import Language.Haskell.TH
tuple :: Int -> ExpQ
tuple n = do
ns <- replicateM n (newName "x")
lamE [foldr (\x y -> conP '(:) [varP x,y]) wildP ns] (tupE $ map varE ns)
Then:
$(tuple 6) [1,2,3,4,5,6] == (1,2,3,4,5,6)
$(tuple 3) "abc" == ('a','b','c')
But in general, if you need this answer, then you're asking the wrong question somewhere.
If you just want flat random access, perhaps the better option would be to use an Array.
If feel like I am about to advise you to point a gun at your foot and trust you not to shoot.
> list2Tuple lst = read $ "(" ++ (init.tail.show) lst ++ ")"
> list2Tuple [1,2,3] :: (Int, Int, Int)
(1,2,3)
> list2Tuple [1,2,3,4] :: (Int, Int, Int, Int)
(1,2,3,4)
This will work up to the what ever length of tuple Show and Read are defined for.
Tuples and lists are very different things. About the best you can do is to manually write a conversion function:
toTuple :: [a] -> (a,a,a,a,a,a)
toTuple [a,b,c,d,e,f] = (a,b,c,d,e,f)
Notice how different the types are: the single variable of the list expands to six variables for the tuple. So you'll need one function for each size of tuple.
I find it difficult to make cogent explanations of Template Haskell manipulations, but here is a demonstration:
> :m +Language.Haskell.TH
> :set -XTemplateHaskell
> runQ [| [1,2,3,4,5,6] |] >>= putStrLn . pprint
[1, 2, 3, 4, 5, 6]
> runQ [| [1,2,3,4,5,6] |] >>= \ (ListE exps) -> putStrLn (pprint (TupE exps))
(1, 2, 3, 4, 5, 6)
I don't think it's possible to do this in Haskell, for a list of arbitrary length not known at compile time. Template Haskell can't do it because it operates only at compile time. I ran into a case where I needed to do precisely this, and I had to work around it. A database library expects different-length tuples for query arguments, but I have an arbitrary-length list. So I have to skirt around the library interface. It would be nice if it could take a list.
Basically the issue is that different-length tuples are different types. But the Haskell compiler has to know at compile type what types might exist at runtime. Converting an arbitrary-length list into a tuple at run time could create some type it didn't know about at compile time.
You can in fact do better than manually writing one function per tuple-size if you use quasi-quotation as explained here. However, I would wonder about code where you expect to use this generically.
When dealing with command line arguments you can use getArgs, that function will give you a list with strings:
getArgs :: IO [String]
Link: https://hackage.haskell.org/package/base-4.16.0.0/docs/System-Environment.html#v:getArgs
When I work with command line arguments I prefer to work with tuples instead of a list, so I convert the list to a tuple. See below:
import System.Environment
main = do
args <- getArgs
let (a:b:c) = args
print a
Calling the program (in PowerShell):
PS C:\Haskell> runghc convertListToTuple goodday to you
"goodday"