Home > database >  How can Haskell code utilise brackets to separate or tidy up information while using list comprehens
How can Haskell code utilise brackets to separate or tidy up information while using list comprehens

Time:10-05

I am trying to write a function where the expression:

crosswordFind letter inPosition len words

should return all the items from words which

  • (i) are of the given length len and
  • (ii) have letter in the position inPosition.

For example, seven-letter words that have ’k’ in position 1, the expression:

crosswordFind ’k’ 1 7 ["funky", "fabulous", "kite", "icky", "ukelele"]

will return

["ukelele"]

Here is what I have so far:

crosswordFind :: Char -> Int -> Int -> [String] -> [String]
crosswordFind letter pos len words = 
    if isAlpha **words** == letter && 
        **words** !! letter == pos && 
        length **pos** == len 
    then words 
    else []

The code above is after altering to remove the brackets that I placed to separate each condition. The code below is the original one (which is wrong):

crosswordFind :: Char -> Int -> Int -> [String] -> [String]
crosswordFind letter pos len words =
   [ if [isAlpha x == letter] && 
        [xs !! n == pos] && 
        [length x == len] 
     then words 
     else [] ]

I understand why it is wrong (because a list of length 1 will be returned), but why can't brackets like these be used to section off code in Haskell?

How can this question be solved using list comprehensions? And I'm wondering what to put in to replace the bolded words as well to make the code run normally.

CodePudding user response:

You can filter with a condition that should satisfy two criteria:

  1. the word has the given length; and
  2. the character on position pos is the given letter.

For a word w of the words we thus check if length w == len and w !! pos == letter.

We thus can implement this with:

crosswordFind :: Eq a => a -> Int -> Int -> [[a]] -> [[a]]
crosswordFind letter pos len words = filter (\w -> length w == len && w !! pos == letter) words

we can also omit the words variable and work with:

crosswordFind :: Eq a => a -> Int -> Int -> [[a]] -> [[a]]
crosswordFind letter pos len = filter (\w -> length w == len && w !! pos == letter)

The above is not very safe: if the pos is greater than or equal to the length, then w !! pos == letter will raise an error. Furthermore for infinite strings (lists of Chars), length will loop forever. I leave it as an exercise to introduce safer variants. You can determine these with recursive functions.

CodePudding user response:

Square brackets are part of list syntax. Nothing else.

Lists.

You can freely utilize round parentheses ( ) for the grouping of expressions.

Some expression types, like let and do, have their own separators {, ;, }, which can also be used, especially to prevent whitespace brittleness.

  • Related