Why does this throw an error?
myTest :: Int -> [Int]
myTest a
| a == 0 = []
| otherwise = x ++ map(myTest) x
where x = [a-1]
I would expect that it would make a list going from a to 1. Instead I get the error:
couldn't match the expected type 'Int' against inferred type '[Int]'
in the first argument of 'map', namely '(myTest)'
in the second argument of '(++)', namely 'map (myTest) x'
This obviously isn't the best way to make this list, but it is a simplified version of a more complicated problem I am having.
I basically have a function foo :: a -> [a], and in the resulting list I need to call foo on every element expanding it into another list. In the end I want one big list where every element is a base case.
I am fairly new at Haskell so I am probably missing something fairly basic.
The signature of myTest is Int -> [Int].
The signature of map is (a -> b) -> [a] -> [b], and since myTest is the first argument, that makes it (Int -> [Int]) -> [Int] -> [[Int]].
But your function expects it to produce an [Int], not an [[Int]].
Edit to add: I think what you want is simply
myTest a
| a == 0 = []
| otherwise = [a] ++ myTest (a-1)
although this is probably not what you should want (it's much more heavyweight than an idiomatic Haskell solution), but without seeing your actual problem that this is a simplification of, it's hard to tell.
myTest :: Int -> [Int]
myTest 0 = []
myTest a = a : myTest (a-1)
Else's answer is better because is uses (:) instead of (++). In your case you can use either, because (:) adds a single element to the front of the list, and that's what you're trying to do.
(++) is a relatively expensive operation because it copies the spine of the left hand list. (:) is cheap because it never copies anything, it just creates a new cons cell that contains your new head element.
So always use (:) instead of (++) if you can.
EDIT: Just trying to explain since Else didn't post an explanation for his code.
Related
I'm trying to code a function that takes a list of string (containing actions to do on the lists inside the tuple) and a tuple of 2 lists of Int as parameters (testReturn).
The function is supposed to execute an action on the Int lists, checks if the first list in the tuple is in ascending order, and then returns a boolean depending on the result.
This code doesn't compile, and I'm not sure about a few things.
My code :
testReturn :: [[Char]] -> ([a], [b]) -> Bool
testReturn [] b = orderedCheck $ fst b
testReturn (a:as) b
| a == "sa" = testReturn as (saFunc $ fst b, snd b)
orderedCheck :: (Ord a) => [a] -> Bool
orderedCheck [] = True
orderedCheck [x] = True
orderedCheck (x:y:xs) = x <= y && orderedCheck (y:xs)
saFunc :: [a] -> [a]
saFunc x
| length x <= 1 = x
saFunc (x:y:xs) = (y:x:xs)
I know that the orderedCheck and saFunc functions work
I'm concerned about :
[[Char]] : Not sure if writing this is right or not, and not sure if it really means a list of strings.
orderedCheck $ fst b : this is the part where I have a GHC error : "No instance for (Ord a) arising from a use of ‘orderedCheck’ ",I looked around and I can't understand what does it mean.
I heard somewhere else that the use of fst and snd may be a bit edgy (is it?), but I don't know how to do without it.
Could you guys please help me understand my errors in order to fix my code?
Thanks!
[[Char]] : Not sure if writing this is right or not, and not sure if it really means a list of strings.
Yes, it does mean a list of strings - that is, the type [String]. This is the same as [[Char]] because in Haskell String and [Char] are type synonyms, literally different ways of referring to the exact same thing. So putting a pair of square brackets round each (to denote a list of that type) also leads to two equivalent types.
String is usually considered more idiomatic than [Char] when writing Haskell code, but it's not a big deal. (Even if you use String everywhere, the compiler might still use [Char] when reporting errors, so it's important to know about this equivalence.)
orderedCheck $ fst b : this is the part where I have a GHC error : "No instance for (Ord a) arising from a use of ‘orderedCheck’ ",I looked around and I can't understand what does it mean.
It's exactly as #Ismor said in the comments - but as I have a little more space in an answer I'll try to give a slightly longer, clearer explanation.
You are calling orderedCheck with the value fst b. And orderedCheck, by your own (correct) type signature, has type (Ord a) => [a] -> Bool. That means its argument must be a list, whose elements are of a type a which satisfies the constraint Ord a.
But you are using it on fst b in testReturn. b is the second argument to the function, which from its type signature must be of type ([a], [b]). This means fst b must be of type [a] - which is a list, so so far so good. But as just mentioned, that type a must have an instance of Ord. And unfortunately we can't guarantee that, because your type signature - [[Char]] -> ([a], [b]) -> Bool - allows both a and b to be absolutely anything. If this code compiled, that type signature would allow me to call that function as, for example, testReturn ["Example"] ([putStrLn "foo"], []) - but putStrLn "foo" has type IO (), which certainly has no Ord instance. (Unless you provide one in your code, which doesn't sound like a great idea - but even if you did, you could easily find another type with no Ord instance which would lead to the same problem.)
The only way to fix this is to fix the type signature of testReturn - it can't actually accept any type as a, because that type must have an Ord instance. So include that requirement, and you'll be fine:
testReturn :: (Ord a) => [[Char]] -> ([a], [b]) -> Bool
(As #MarkSeemann notes, that's exactly the signature GHC would have inferred for you if you'd left out any type signature. I certainly don't recommend leaving off type signatures for top-level functions, but if you're ever not sure of what the signature should be, this technique of leaving it out and then asking GHCi to infer it for you with :t is almost guaranteed to give you what you want.)
I heard somewhere else that the use of fst and snd may be a bit edgy (is it?), but I don't know how to do without it.
I'm not sure what "edgy" means in this context. It's certainly not "wrong", nor is it dangerous in the same way that head and tail are for lists - those functions will crash (at runtime) when given an empty list, whereas fst and snd will work fine for any 2-tuple (and if given a value that's not a 2-tuple, your code will fail to compile - so there is zero risk of a runtime crash).
However, it's not very elegant compared to pattern-matching, which here is rather like "destructuring" in other languages. I think most Haskellers would write your function like this instead, which is equivalent to your code and hopefully self-explanatory:
testReturn [] (b, _) = orderedCheck b
testReturn (a:as) (b, c)
| a == "sa" = testReturn as (saFunc b, c)
(Note that this function appears incomplete, and will crash if called with a non-empty first argument whose first element is anything other than "sa".)
So this one seems like it should be super-simple... but I'm not sure where to stick the 'fold' in (obviously you could fold either way)...
It says "write a function ( intToString :: [Int] -> [Char] ) using a fold, that mimics this map:
map intToDigit [5,2,8,3,4] == "52834"
And then says, "For the conversion, use intToDigit :: Int -> Char from Data.Char."
I'm not entirely sure I get the point... but yet it doesn't seem like it should be that hard -- you're just reading in the list (folding it in, I get how folds work in general) from either the left or right and doing the conversion... but I'm not sure how to set it up.
It is not difficult, think about the definition foldr (or foldl) of List:
foldr::(a -> b -> b) -> b -> [a] -> b
Here (a->b->b) is the step function which will be applied on each element of list [a], b is your target.
Now, you have a list of Int ([Int]), and need to convert to [Char] (or String).
Relpace [a] by [5,2,8,3,4], b by []::[Char] (your target) and (a->b->b) by step function :
foldr step ([]::[Char]) [5,2,8,3,4]
We have known that step function has type (a->b->b), specifically, (Int->[Char]->[Char]), the job need to do just convert Int to [Char], as mentioned in question: intToDigit can be helped to convert Int to Char and (:) operator can append element at the head of List so:
step x s = intToDigit x : s
where s is [Char] (or String), put them all:
foldr (\x s->intToDigit x : s) [] [5,2,8,3,4]
So basically i'm taking a list of items and adding to a list of tuples to make it more efficient way to store/view the data. My code is
TList :: [a] -> a -> [(a,Int)] -> [(a,Int)]
TList head [a] [] = [(head [a],1)]
TList head [a] ((a',i):xa)
|a' == take 1 = (head 1,i+1):xa
|otherwise = (a',i) : TList drop 1 [a] xa
so my logic is that I take the first item in the list, checks to see if its already in the tuple list, if it is add one to the int. the call the function again but without the first list item
but it keeps giving the error
Couldn't match expected type '[t1] -> a' with actual type '[a]'
it gives this error 5 times, one for each line.
So, this is not a full answer to your question because I'm not sure what exactly you're trying to achieve. But there's a few things wrong with the code and I suggest you start by fixing them and then seeing how it goes:
Function names need to begin with a lower-case letter. Therefore, TList is not a legal name for a function. (Types and type constructors have upper case names). So maybe you want tList?
You are naming one of the parameters head. But head is also a Prelude function and you actually seem to use the head function (head [a]). But your parameter head will shadow the head function. Also head seems like an odd name for a proper list.
head [a] seems odd as head [a] == a. So the head of a list with just one element is always just that element.
I'm guessing you're trying to use drop 1 [a] (if so, you're missing parenthesis). That's odd too because drop 1 [a] == []. drop 1 of a list with just one element is always the empty list.
You're pattern matching the second parameter (type a) with [a] and that can't work because [a] only works with list types [t].
a' == take 1 doesn't really make sense. take 1 needs a list as the second argument take 1 [1, 2, 3] = [1]. So you're comparing something (a) of type a with another thing of type [a] -> [a] (take 1 :: [a] -> [a]).
When you wrote:
TList head [a] [] = ...
You've shadowed the original head function. Thus in this context:
[(head [a],1)]
It tries to evaluate it. I've no idea why haven'y you just used a here, the code is very unclear and it won't compile with that name (uppercase TList), but this is the source of this type mismatch.
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).
For a silly challenge I am trying to implement a list type using as little of the prelude as possible and without using any custom types (the data keyword).
I can construct an modify a list using tuples like so:
import Prelude (Int(..), Num(..), Eq(..))
cons x = (x, ())
prepend x xs = (x, xs)
head (x, _) = x
tail (_, x) = x
at xs n = if n == 0 then xs else at (tail xs) (n-1)
I cannot think of how to write an at (!!) function. Is this even possible in a static language?
If it is possible could you try to nudge me in the right direction without telling me the answer.
There is a standard trick known as Church encoding that makes this easy. Here's a generic example to get you started:
data Foo = A Int Bool | B String
fooValue1 = A 3 False
fooValue2 = B "hello!"
Now, a function that wants to use this piece of data must know what to do with each of the constructors. So, assuming it wants to produce some result of type r, it must at the very least have two functions, one of type Int -> Bool -> r (to handle the A constructor), and the other of type String -> r (to handle the B constructor). In fact, we could write the type that way instead:
type Foo r = (Int -> Bool -> r) -> (String -> r) -> r
You should read the type Foo r here as saying "a function that consumes a Foo and produces an r". The type itself "stores" a Foo inside a closure -- so that it will effectively apply one or the other of its arguments to the value it closed over. Using this idea, we can rewrite fooValue1 and fooValue2:
fooValue1 = \consumeA consumeB -> consumeA 3 False
fooValue2 = \consumeA consumeB -> consumeB "hello!"
Now, let's try applying this trick to real lists (though not using Haskell's fancy syntax sugar).
data List a = Nil | Cons a (List a)
Following the same format as before, consuming a list like this involves either giving a value of type r (in case the constructor was Nil) or telling what to do with an a and another List a, so. At first, this seems problematic, since:
type List a r = (r) -> (a -> List a -> r) -> r
isn't really a good type (it's recursive!). But we can instead demand that we first reduce all the recursive arguments to r first... then we can adjust this type to make something more reasonable.
type List a r = (r) -> (a -> r -> r) -> r
(Again, we should read the type List a r as being "a thing that consumes a list of as and produces an r".)
There's one final trick that's necessary. What we would like to do is to enforce the requirement that the r that our List a r returns is actually constructed from the arguments we pass. That's a little abstract, so let's give an example of a bad value that happens to have type List a r, but which we'd like to rule out.
badList = \consumeNil consumeCons -> False
Now, badList has type List a Bool, but it's not really a function that consumes a list and produces a Bool, since in some sense there's no list being consumed. We can rule this out by demanding that the type work for any r, no matter what the user wants r to be:
type List a = forall r. (r) -> (a -> r -> r) -> r
This enforces the idea that the only way to get an r that gets us off the ground is to use the (user-supplied) consumeNil function. Can you see how to make this same refinement for our original Foo type?
If it is possible could you try and nudge me in the right direction without telling me the answer.
It's possible, in more than one way. But your main problem here is that you've not implemented lists. You've implemented fixed-size vectors whose length is encoded in the type.
Compare the types from adding an element to the head of a list vs. your implementation:
(:) :: a -> [a] -> [a]
prepend :: a -> b -> (a, b)
To construct an equivalent of the built-in list type, you'd need a function like prepend with a type resembling a -> b -> b. And if you want your lists to be parameterized by element type in a straightforward way, you need the type to further resemble a -> f a -> f a.
Is this even possible in a static language?
You're also on to something here, in that the encoding you're using works fine in something like Scheme. Languages with "dynamic" systems can be regarded as having a single static type with implicit conversions and metadata attached, which obviously solves the type mismatch problem in a very extreme way!
I cannot think of how to write an at (!!) function.
Recalling that your "lists" actually encode their length in their type, it should be easy to see why it's difficult to write functions that do anything other than increment/decrement the length. You can actually do this, but it requires elaborate encoding and more advanced type system features. A hint in this direction is that you'll need to use type-level numbers as well. You'd probably enjoy doing this as an exercise as well, but it's much more advanced than encoding lists.
Solution A - nested tuples:
Your lists are really nested tuples - for example, they can hold items of different types, and their type reveals their length.
It is possible to write indexing-like function for nested tuples, but it is ugly, and it won't correspond to Prelude's lists. Something like this:
class List a b where ...
instance List () b where ...
instance List a b => List (b,a) b where ...
Solution B - use data
I recommend using data construct. Tuples are internally something like this:
data (,) a b = Pair a b
so you aren't avoiding data. The division between "custom types" and "primitive types" is rather artificial in Haskell, as opposed to C.
Solution C - use newtype:
If you are fine with newtype but not data:
newtype List a = List (Maybe (a, List a))
Solution D - rank-2-types:
Use rank-2-types:
type List a = forall b. b -> (a -> b -> b) -> b
list :: List Int
list = \n c -> c 1 (c 2 n) -- [1,2]
and write functions for them. I think this is closest to your goal. Google for "Church encoding" if you need more hints.
Let's set aside at, and just think about your first four functions for the moment. You haven't given them type signatures, so let's look at those; they'll make things much clearer. The types are
cons :: a -> (a, ())
prepend :: a -> b -> (a, b)
head :: (a, b) -> a
tail :: (a, b) -> b
Hmmm. Compare these to the types of the corresponding Prelude functions1:
return :: a -> [a]
(:) :: a -> [a] -> [a]
head :: [a] -> a
tail :: [a] -> [a]
The big difference is that, in your code, there's nothing that corresponds to the list type, []. What would such a type be? Well, let's compare, function by function.
cons/return: here, (a,()) corresponds to [a]
prepend/(:): here, both b and (a,b) correspond to [a]
head: here, (a,b) corresponds to [a]
tail: here, (a,b) corresponds to [a]
It's clear, then, that what you're trying to say is that a list is a pair. And prepend indicates that you then expect the tail of the list to be another list. So what would that make the list type? You'd want to write type List a = (a,List a) (although this would leave out (), your empty list, but I'll get to that later), but you can't do this—type synonyms can't be recursive. After all, think about what the type of at/!! would be. In the prelude, you have (!!) :: [a] -> Int -> a. Here, you might try at :: (a,b) -> Int -> a, but this won't work; you have no way to convert a b into an a. So you really ought to have at :: (a,(a,b)) -> Int -> a, but of course this won't work either. You'll never be able to work with the structure of the list (neatly), because you'd need an infinite type. Now, you might argue that your type does stop, because () will finish a list. But then you run into a related problem: now, a length-zero list has type (), a length-one list has type (a,()), a length-two list has type (a,(a,())), etc. This is the problem: there is no single "list type" in your implementation, and so at can't have a well-typed first parameter.
You have hit on something, though; consider the definition of lists:
data List a = []
| a : [a]
Here, [] :: [a], and (:) :: a -> [a] -> [a]. In other words, a list is isomorphic to something which is either a singleton value, or a pair of a value and a list:
newtype List' a = List' (Either () (a,List' a))
You were trying to use the same trick without creating a type, but it's this creation of a new type which allows you to get the recursion. And it's exactly your missing recursion which allows lists to have a single type.
1: On a related note, cons should be called something like singleton, and prepend should be cons, but that's not important right now.
You can implement the datatype List a as a pair (f, n) where f :: Nat -> a and n :: Nat, where n is the length of the list:
type List a = (Int -> a, Int)
Implementing the empty list, the list operations cons, head, tail, and null, and a function convert :: List a -> [a] is left as an easy exercise.
(Disclaimer: stole this from Bird's Introduction to Functional Programming in Haskell.)
Of course, you could represent tuples via functions as well. And then True and False and the natural numbers ...