This is actually a good use-case for regular expressions. In Haskell you have regex-applicative which is also a parser combinator library, except it is not monadic, and for that reason is restricted to regular languages.
Here is how a parser might look like:
{-# LANGUAGE RecordWildCards #-}moduleMigratumRegex(MigrationFile,prettyMigrationFile,parseMigrationFile)whereimportControl.Applicative(some)importData.Char(isAlphaNum)importData.Version(Version,makeVersion,showVersion)importText.Regex.Applicative(RE,sym,psym,string,(=~))importText.Regex.Applicative.Common(decimal)dataMigrationFile=MigrationFile{mfVersion::Version,mfName::FilePath}deriving(Eq,Show)typeParsera=RECharaprettyMigrationFile::MigrationFile->StringprettyMigrationFileMigrationFile{..}="V"<>showVersionmfVersion<>"__"<>mfName<>".sql"parseMigrationFile::String->MaybeMigrationFileparseMigrationFile=(=~migrationFile)-- V<version number>__<file name>.sqlmigrationFile::ParserMigrationFilemigrationFile=MigrationFile<$>(sym'V'*>version)<*>(string"__"*>filename<*string".sql")version::ParserVersionversion=fmap(makeVersion.pure)decimalfilename::ParserFilePathfilename=some(psymisAlphaNum)
Excellent!
This is actually a good use-case for regular expressions. In Haskell you have regex-applicative which is also a parser combinator library, except it is not monadic, and for that reason is restricted to regular languages.
Here is how a parser might look like:
And here it is in action: