map the min command to a multilevel list in haskell - haskell

I want to find the smallest values in a set of lists
map min [[1, 3], [2, 7],[9, 6]]
I would like this to output
[[1],[2],[6]]
It gives the error:
* No instance for (Show ([Integer] -> [Integer]))
arising from a use of `print'
(maybe you haven't applied a function to enough arguments?)
* In a stmt of an interactive GHCi command: print it

min :: Ord a => a -> a -> a works on two items to return the minimum of the two. You are probably looking for minimum :: (Foldable f, Ord a) => f a -> a instead:
Prelude> map minimum [[1, 3], [2, 7],[9, 6]]
[1,2,6]
Here the items are not wrapped in individual sublists, but that would only result in an (unnecessary) extra layer of indirection.

Related

How can I make a histogram from a list of integers in Haskell? [duplicate]

This question already has an answer here:
How can I compute a histogram in Haskell?
(1 answer)
Closed 2 years ago.
I'm a Haskell beginner. What's the easiest way of making a histogram from a list of integers? Say I have a list like this:
l = [1, 2, 3, 5, 7, 7, 7, 10]
I'd want to be able to histogram 2 l (for 2 bins) and have it return:
[(0, 3), (1, 5)]
Since there are three numbers in the 0th (first) half, and five numbers in the other half.
There are a lot of libraries that seem to do this, but marshalling a list of integers to and from Vectors or other data structures is really confusing me.
Here's one thing I've tried:
import Statistics.Sample.Histogram
l = [1, 2, 3, 5, 6, 7, 7, 7, 7] :: [Double]
main = print $ snd $ histogram 10 l
But the error it throws is:
histogram-test.hs:6:8: error:
• Ambiguous type variables ‘v10’,
‘b0’ arising from a use of ‘print’
prevents the constraint ‘(Show (v10 b0))’ from being solved.
Probable fix: use a type annotation to specify what ‘v10’,
‘b0’ should be.
These potential instances exist:
instance Show a => Show (Maybe a) -- Defined in ‘GHC.Show’
instance (Show a, Show b) => Show (a, b) -- Defined in ‘GHC.Show’
instance (Show a, Show b, Show c) => Show (a, b, c)
-- Defined in ‘GHC.Show’
...plus 13 others
...plus 19 instances involving out-of-scope types
(use -fprint-potential-instances to see them all)
• In the expression: print $ snd $ histogram 10 l
In an equation for ‘main’: main = print $ snd $ histogram 10 l
|
6 | main = print $ snd $ histogram 10 l
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
histogram-test.hs:6:22: error:
• No instance for (Data.Vector.Generic.Base.Vector [] Double)
arising from a use of ‘histogram’
• In the second argument of ‘($)’, namely ‘histogram 10 l’
In the second argument of ‘($)’, namely ‘snd $ histogram 10 l’
In the expression: print $ snd $ histogram 10 l
|
6 | main = print $ snd $ histogram 10 l
| ^^^^^^^^^^^^^^
Failed, no modules loaded.
I think you have to be forcefully explicit with the data types you expect to get.
$ ghci
GHCi, version 8.6.5: http://www.haskell.org/ghc/ :? for help
...
λ>
λ> import qualified Data.Vector as V
λ> import Statistics.Sample.Histogram
λ>
λ> l = [1, 2, 3, 5, 6, 7, 7, 7, 7] :: [Double]
λ> hi = (histogram 10 (V.fromList l)) :: (V.Vector Double, V.Vector Int)
λ>
λ> part2 = snd hi
λ>
λ> part2
[1,1,0,1,0,0,1,1,0,4]
λ>
Also, it could be that the statistics folks are overwhelmingly of the Fortran/C/C++ culture, and consequently they regard Haskell lists as nice stuff for computer scientists; however, when doing statistics, lists are expected to be converted into some serious data type, like sequence or vector.
What this error line:
No instance for (Data.Vector.Generic.Base.Vector [] Double)
means to tell us is that a list cannot make a proper vector, that is a proper food for function histogram. You have to allow explicitely the compiler to convert from list to vector.
It is quite easy to implement this yourself without relying on any library (other than containers, to provide a Map type for the result):
frequencies :: Ord a => [a] -> M.Map a Int
frequencies = foldr (\x m -> M.insertWith (+) x 1 m) M.empty

Trying to understand zip

I am attempting to understand how to use zip in Haskell. I've been learning Haskell recently and am trying to create a list of tuples from two separate lists
I have the following:
createList :: [Char] -> [Char] -> [(Char,Char)]
createList xs ys = zip(xs,ys)
I understand zip is supposed to create a list of tuples given two lists, but I get the following error:
Couldn't match expected type ‘[a0]’
with actual type ‘([Char], [Char])’
Can anyone explain to me where I am stumbling?
Haskell function calls don't use brackets or commas.
You can write the createList function as:
createList xs ys = zip xs ys
or simply
createList = zip
Thus, the createList function is redundant; it's just zip. The only potential use for the alias that I can think of is if you truly want to constrain the type as given.
If you remove the parenthesis around zip call, your code should work:
createList :: [Char] -> [Char] -> [(Char,Char)]
createList xs ys = zip xs ys
Explanation:
Full error I am getting when I run zip ([1, 2, 3], [4, 5, 6]) (notice the parens):
<interactive>:4:5:
Couldn't match expected type ‘[a]’
with actual type ‘([Integer], [Integer])’
Relevant bindings include
it :: [b] -> [(a, b)] (bound at <interactive>:4:1)
In the first argument of ‘zip’, namely ‘([1, 2, 3], [4, 5, 6])’
In the expression: zip ([1, 2, 3], [4, 5, 6])
In an equation for ‘it’: it = zip ([1, 2, 3], [4, 5, 6])
Notice the part that says In the first argument of ‘zip’, namely ‘([1, 2, 3], [4, 5, 6])’. The parens are interpreted as tuple constructor. zip function expects a list as its first argument but we are passing it a tuple.

Instantiate Show typeclass for a custom NestedList type

I have defined the following custom type of arbitrary deep lists
data NestedList a
= Elem a
| List [NestedList a]
and I want to instantiate Show and pretty print my nested lists, but I don't have any idea about how the show function should look for my type
instance (Show a) => Show (NestedList a) where
for example if we have
let a = List [List[Elem 2], Elem 1, List[Elem 1, Elem 2],
List[List[Elem 2, Elem 3]], Elem 5]
I want show a to print
"[[2], 1, [1, 2], [[2, 3]], 5]"
How can I implement the show function?
I believe this is the instance you want:
data NestedList a = Elem a | List [NestedList a]
instance (Show a) => Show (NestedList a) where
show (Elem a) = show a
show (List xs) = "[" ++ intercalate ", " (map show xs) ++ "]"
Note that you will need to import intercalate from Data.List. (This is different from intersperse which I mentioned in my comment - apologies that in haste I picked the wrong one.)
I hope this makes sense when you've seen it - we simply borrow the show instance for a to treat the Elem a case. Then the List case displays all the elements, puts the string ", " between each, and encloses the whole in square brackets.
Proof that it works on your example:
Prelude Data.List> :{
Prelude Data.List| let a = List [List[Elem 2], Elem 1, List[Elem 1, Elem 2],
Prelude Data.List| List[List[Elem 2, Elem 3]], Elem 5]
Prelude Data.List| :}
Prelude Data.List> a
[[2], 1, [1, 2], [[2, 3]], 5]
You do not have to implement Show, just ask the compiler to derive it:
data NestedList a = Elem a | List [NestedList a]
deriving Show
The Show typeclass is typically reserved for printing values in a format that can be read back by the language.
Derived instances of Show have the following properties, which are compatible with derived instances of Text.Read.Read: * The result of show is a syntactically correct Haskell expression containing only constants, given the fixity declarations in force at the point where the type is declared. It contains only the constructor names defined in the data type, parentheses, and spaces. When labelled constructor fields are used, braces, commas, field names, and equal signs are also used.
By convention, your function should be defined separately from the Show typeclass instance.

How to avoid print-related defaulting warning in GHCi

This code is for an exercise in a textbook.
If I define
minmax :: (Ord a, Show a) => [a] -> Maybe (a, a)
minmax [] = Nothing
minmax [x] = Just (x, x)
minmax (x:xs) = Just ( if x < xs_min then x else xs_min
, if x > xs_max then x else xs_max
) where Just (xs_min, xs_max) = minmax xs
...then, in ghci I get warnings like these:
*...> minmax [3, 1, 4, 1, 5, 9, 2, 6]
<interactive>:83:1: Warning:
Defaulting the following constraint(s) to type ‘Integer’
(Num a0) arising from a use of ‘it’ at <interactive>:83:1-31
(Ord a0) arising from a use of ‘it’ at <interactive>:83:1-31
(Show a0) arising from a use of ‘print’ at <interactive>:83:1-31
In the first argument of ‘print’, namely ‘it’
In a stmt of an interactive GHCi command: print it
Just (1,9)
I had expected that having Show a in the context for minmax's type signature would have eliminated such warnings. I don't understand why this is not enough.
What else must I do to eliminate such warnings? (I'm particularly interested in solutions that do not require defining a new type expressly for the value returned by minmax.)
Numeric literals have polymorphic types, and so do lists of them:
GHCi> :t 3
3 :: Num t => t
GHCi> :t [3, 1, 4, 1, 5, 9, 2, 6]
[3, 1, 4, 1, 5, 9, 2, 6] :: Num t => [t]
To get rid of the warnings, specify the type of the list (or of its elements, which boils down to the same thing). That way, there will be no need for defaulting:
GHCi> minmax ([3, 1, 4, 1, 5, 9, 2, 6] :: [Integer])
Just (1,9)
GHCi> minmax [3 :: Integer, 1, 4, 1, 5, 9, 2, 6]
Just (1,9)
See also Exponents defaulting to Integer for related suggestions involving a slightly different scenario.

Simple print in haskell script: how to write main function?

I am starting to learn haskell, but cannot find a way to have a working main function. I have already made it work somehow, but I think it was pure luck because I cannot get it again.
Basically, what I want to do is create a script file to be run like runhaskell script.hs from terminal.
So the basic structure would be the function declaration followed by a main = do or something, and the function being called to print its result.
For example, I took this from "Learn you a Haskell", but the following code doesn't work:
elem' :: (Eq a) => a -> [a] -> Bool
elem' y ys = foldl (\acc x -> if x == y then True else acc) False ys
main :: IO()
main = print (elem' 1 [1,2,3,4])
This gives me the error:
Build FAILED
/home/helton/Desktop/apaga.hs: line 6, column 16:
Warning: Defaulting the following constraint(s) to type `Integer'
(Eq a0)
arising from a use of elem'
at /home/helton/Desktop/apaga.hs:6:16-20
(Num a0)
arising from the literal `1' at /home/helton/Desktop/apaga.hs:6:22
In the first argument of `print', namely `(elem' 1 [1, 2, 3, 4])'
In a stmt of a 'do' block: print (elem' 1 [1, 2, 3, 4])
In the expression: do { print (elem' 1 [1, 2, 3, 4]) }
print (elem' 1 [1,2,3,4])
While I expected something like
> True
Try replacing
print (elem' 1 [1, 2, 3, 4])
with
print (elem' (1::Int) [1, 2, 3, 4])
The issue here is that Haskell can't determine whether your numeric literals should be interpreted as Ints or Doubles or any other numeric type.
Specifying the type for any numeric literal here is enough, since elem' requires all of them to be of the same type, hence once the type of any one of them is known such type can be used for everything else.

Resources