Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using isUpper, isLower, and isDigit in Haskell

Tags:

haskell

I am having trouble with how to use isUpper, isLower, and isDigit. Specifically I am trying to take a string and return a list of tuples for each character in the string containing three Bool values for if the character is an uppercase letter, a lowercase letter, or a digit. So the string "Ab2" would return the list [(True, False, False), (False, True, False), (False, False, True)]. This is what I have:

import Data.Char
uppercaseList :: [a] -> [(Bool, Bool, Bool)]
uppercaseList xs = [(isUpper, isLower, isDigit)]

I think I need to pass the character of the string into isUpper, isLower, and isDigit, but I don't see how to. I'm sorry if this is a dumb question, but nothing I've found addresses my confusion so far.

like image 658
Matt Robbins Avatar asked Sep 14 '17 06:09

Matt Robbins


People also ask

What is the use of Islower () and Isupper () method in C?

The functions isupper() and islower() in C++ are inbuilt functions present in “ctype. h” header file. It checks whether the given character or string is in uppercase or lowercase.

What is the use of Islower () and Isupper () function give example also?

Python String isupper() is a built-in function that returns “True” if all the characters in the string are uppercase. The String islower() is a built-in function that returns “True” if all the characters in the string are lowercase. These are the built-in method used for string handling.

What is the difference between Isupper and upper in Python?

The isupper() & islower() return boolean values whereas the upper() & lower() function returns strings either in uppercase or lowercase.


2 Answers

You need to do check on each element of the list (xs). Usually this kind of task is done by using map

import Data.Char
uppercaseList :: String -> [(Bool, Bool, Bool)]
uppercaseList xs = map (\x -> (isUpper x, isLower x, isDigit x)) xs

or list comprehension

uppercaseList xs = [ (isUpper x, isLower x, isDigit x) | x <- xs ]

or write from scratch

uppercaseList [] = []
uppercaseList (x:xs) = (isUpper x, isLower x, isDigit x) : uppercaseList xs
like image 92
delta Avatar answered Oct 16 '22 10:10

delta


The problem with your approach:

uppercaseList xs = [(isUpper, isLower, isDigit)]

is that it does not take the list xs into account at all: it is not mentioned in the body. So that means xs has no impact on the output.

What you have done ihere is constructing a list as output with one element: a tuple that contains three functions (yes these are functions, not Bools).

In order to inspect the character, you need to call the functions on an element of the list.

Calling a function on a list is done with map :: (a -> b) -> [a] -> [b]. Map takes as first argument a function f, and as second argument a list of elements (for instance [x1, x2, x3, x4]). It applies the function f on all elements of the input, and generates a list [f x1, f x2, f x3, f x4]). This is done in a lazy manner.

Here we thus need a function f :: Char -> (Bool, Bool, Bool). Based on the specifications, the function looks like:

import Data.Char(isUpper, isLower, isDigit)

f :: Char -> (Bool, Bool, Bool)
f x = (isUpper x, isLower x, isDigit x)

We can then write:

uppercaseList :: [Char] -> [(Bool, Bool, Bool)]
uppercaseList = map f

Since it is weird to see a function f (we can of course give it a more semantical name), at the top level of a file. We can decide to scope it (or use a lambda expression instead):

uppercaseList :: [Char] -> [(Bool, Bool, Bool)]
uppercaseList = map f
    where f x = (isUpper x, isLower x, isDigit x)
like image 27
Willem Van Onsem Avatar answered Oct 16 '22 11:10

Willem Van Onsem