1

I am trying to create an anagram lookup in haskell, I am getting a parse error on input "f"

Here is my code

import Data.Map (Map)
import Data.List (sort)
import qualified Data.Map as M

type Anagrams = Map String [String]

main :: IO()
main = buildAnagrams "dictionary.txt" >>= loop
  where
    loop :: Anagrams -> IO ()
    loop anagrams = forever $ do
         putStrLn "Anagrams of..."
         getLine >>=  print . lookupAnagrams anagrams


buildAnagrams :: FilePath -> IO Anagrams
buildAnagrams = fmap (foldr f M.empty . lines ) . readFile
  where 
     f :: String -> Anagrams -> Anagrams
     f s = M.insertWith (++) (sort s) [s]

lookupAnagrams :: Anagrams -> String -> [String]
lookupAnagrams anagrams str =   
    case M.Lookup(sort str) anagrams of
        Nothing -> []
        Just XS -> XS

the error is on the line f s = M.insertWith

hnefatl
  • 5,860
  • 2
  • 27
  • 49
Ftuvida
  • 11
  • 2

2 Answers2

1

I have 3 errors with your code, neither of which is a parse error. Error messages differ between compiler versions, so it is hard for me to know exactly what you see.

These are the errors I had to fix to have your code compile:

  1. Add the line import Control.Monad (forever).
  2. Fix the identifier case in the expression case M.lookup (sort str) anagrams of ....
  3. Fix the identifier case in the line Just xs -> xs.

(Overall, you could also replace that case with a fromMaybe. It would be idiomatic and concise.)

In Haskell you distinguish the sort of an identifier by the case of the first character. If the identifier starts with a capital letter, it would mean it is either a data constructor, a type constructor or a module name. For ordinary values (and type variables), you always start with lower case.

I hope this helps you. Let me know if the problem persists.

Ignat Insarov
  • 4,660
  • 18
  • 37
1

You have a tab character forming part of the whitespace on the line that you indicated the parse error is on. Precisely, in the code in your post above, you have this line (» is tab, · is space):

··»·····f :: ...

Haskell is a whitespace sensitive language - in particular, it's a lot easier and less error-prone to just use spaces instead of tabs, and mixing them rarely works.

Replacing any tabs with spaces should fix your parse error - if your editor has a "tabs to spaces" conversion option, that's a good thing to enable. To fix the other errors present in your code, Ignat Insarov has already given a good answer.

hnefatl
  • 5,860
  • 2
  • 27
  • 49
  • How did you find out? I passed the code through `xxd` and see no occurences of a `0x09` character. – Ignat Insarov Apr 14 '18 at 11:18
  • @IgnatInsarov It's not shown in the code in the post, but if you hit [edit](https://stackoverflow.com/posts/49828678/edit) and skip your cursor along the whitespace before that line, it'll jump 2 spaces instead of one. The "ask question" dialog doesn't easily allow tabs to be entered directly, so it's extremely likely the OP pasted the tab in from their code - and it matches the error message they get. I used to have this issue a lot, so I'm uncomfortably aware of the possibility. – hnefatl Apr 14 '18 at 11:21
  • Oh. I see. Thanks! – Ignat Insarov Apr 14 '18 at 11:29