Macha
Macha

Reputation: 14654

Pattern Matching a Haskell list of variable size

EDIT: I shouldn't be coding when this tired. I was compiling a different copy of the program than I was running. Sorry for wasting your time.

I have the following code to make a single argument optional in my program's startup.

main = do
    args <- getArgs
    handleArgs args

handleArgs :: [String] -> IO ()
handleArgs (server:nick:channel:[]) = IRC.startIRC server 6667 nick channel
handleArgs (server:port:nick:channel:[]) = IRC.startIRC server (read port :: Int) nick    channel
handleArgs _ = putStrLn "Incorrect arguments given."

If I run it like ./program irc.freenode.net 6667 somenick #somechannel, it runs. However, if I run it like ./program irc.freenode.net somenick #somechannel, which should make args be a list "irc.freenode.net":"somenick":"#somechannel":[] if I understand it correctly, it gives a pattern match error pointing to the args <- getArgs line when I try to run it after compiling with ghc.

More precisely, the error is: mbot: user error (Pattern match failure in do expression at core.hs:9:4-32)

Upvotes: 1

Views: 2380

Answers (3)

R&#252;diger Hanke
R&#252;diger Hanke

Reputation: 6255

Check that your shell is not interpreting the part starting with # as a comment, e.g. bash with interactive_comments on (shopt). #somechannel may be interpreted as a comment.

Upvotes: 4

Thomas M. DuBuisson
Thomas M. DuBuisson

Reputation: 64740

Could not reproduce:

import System.Environment (getArgs)
main = do
    args <- getArgs
    handleArgs args

handleArgs :: [String] -> IO ()
handleArgs (server:port:nick:channel:xs) = print 4
handleArgs (server:nick:channel:xs) = print 3

Output:

$ ghc --make match.hs
[1 of 1] Compiling Main             ( match.hs, match.o )
Linking match ...
$ ./match
match: match.hs:(7,0)-(8,44): Non-exhaustive patterns in function handleArgs

$ ./match a b c
3
$ ./match a b c d
4
$ ghc -V
The Glorious Glasgow Haskell Compilation System, version 6.12.1

I think you're problem is elsewhere. Perhaps you could make a minimal piece of code that actually complies and exhibits the problem? That is usually an informative exercise.

Upvotes: 1

Fiona Runge
Fiona Runge

Reputation: 2311

I think, your problem comes from the use of xs in both patterns, when it would be fitting to match against []

foobar :: [String] -> String
foobar (a:b:[]) = b         -- matches on exactly two items
foobar (a:b:c:[]) = c -- matches on exactly three items
foobar _ = "hurz?"

This example works for me, and should hopefully do so for you, too .)

  • Thing is, that matching against xs matches the empty list aswell as any other remaining tail.

Upvotes: 2

Related Questions