Theres is a little problem I want to solve with Haskell:
let substitute a function that change all of the wildcards in a string for one concrete parameter. The function has de signature of:
subs :: String -> String -> String -> String
-- example:
-- subs 'x' "x^3 + x + sin(x)" "6.2" will generate
-- "6.2^3 + 6.2 + sin(6.2)"
You could use the Text.Regex package.
Your example might look something like this:
import Text.Regex(mkRegex, subRegex)
subs :: String -> String -> String -> String
subs wildcard input value = subRegex (mkRegex wildcard) input value
See http://bluebones.net/2007/01/replace-in-haskell/ for an example which looks exactly as the piece of code you are looking for.
You can use text-format-simple library for such cases:
import Text.Format
format "{0}^3 + {0} + sin({0})" ["6.2"]
Use regular expressions (Text.Regex.Posix) and search-replace for /\Wx\W/ (Perl notation). Simply replacing x to 6.2 will bring you trouble with x + quux.
Haskell Regex Replace for more information (I think this should be imported to SO.
For extra hard-core you could parse your expression as AST and do the replacement on that level.
Related
Can I always expect the single single-quote syntax to desugar to the NameG constructor? e.g. does
'x
always desugar to
(Name (OccName "x") (NameG VarName (PkgName "some-package") (ModName "SomeModule")))
This information must always be there, after name resolution, which is the stage Template Haskell runs after, right? And I haven't been able to quote local names, though I'm only interested in quoting top-level names.
Context: I want to write a function that returns the uniquely-qualified identifier. It's a partial function because I can't constrain the input, as Template Haskell doesn't have any GADTs or anything, while I don't want to wrap the output in uncertainty. And I don't want to use a quasi-quoter or splice, if ' will do. I want to prove that this partial function is safe at runtime when used as above, quoting top-level names in the same module, given:
name (Name occ (NameG _ pkg mod)) = Unique occ pkg mod
I want to have a function like:
(<=>) :: Name -> a -> Named a
given:
data Named a = Named a Unique
to annotate variable bindings:
x = 'x
<=> ...
without the user needing to use the heavy splice syntax $(name ...), and invoke splicing at compile time:
x = $(name 'x)
<=> ...
The user will be writing a lot of these, for configuration.
https://downloads.haskell.org/~ghc/7.8.3/docs/html/users_guide/template-haskell.html and https://hackage.haskell.org/package/template-haskell-2.8.0.0/docs/src/Language-Haskell-TH-Syntax.html#Name didn't say.
(p.s. I'd also like to know if the double single-quote syntax (e.g. ''T) had the analogous guarantee, though I'd expect them to be the same).
Since ' quoted names are known at compile time, why don't you change name to be in the Q monad:
name :: Name -> ExpQ
name (Name occ (NameG _ pkg mod)) = [| Unique occ pkg mod |]
name n = fail $ "invalid name: "++ gshow n
Then you use $(name 'show) :: Unique instead of name 'show :: Unique. If you get an invalid Name (say somebody uses mkName), that failure will show up at compile time.
** old**
Suppose we have a pattern ex. "1101000111001110".
Now I have a pattern to be searched ex. "1101". I am new to Haskell world, I am trying it at my end. I am able to do it in c but need to do it in Haskell.
Given Pattern := "1101000111001110"
Pattern To Be Searched :- "110
Desired Output:-"Pattern Found"`
** New**
import Data.List (isInfixOf)
main = do x <- readFile "read.txt"
putStr x
isSubb :: [Char] -> [Char] -> Bool
isSubb sub str = isInfixOf sub str
This code reads a file named "read", which contains the following string 110100001101. Using isInfixOf you can check the pattern "1101" in the string and result will be True.
But the problem is i am not able to search "1101" in the string present in "read.txt".
I need to compare the "read.txt" string with the user provided string. i.e
one string is their in the file "read.txt"
and second string user will provid (user defined) and we will perform search and find whether user defined string is present in the string present in "read.txt"
Answer to new:
To achieve this, you have to use readLn:
sub <- readLn
readLn accepts input until a \n is encountered and <- binds the result to sub. Watch out that if the input should be a string you have to explicitly type the "s around your string.
Alternatively if you do not feel like typing the quotation marks every time, you can use getLine in place of readLn which has the type IO String which becomes String after being bound to sub
For further information on all functions included in the standard libraries of Haskell see Hoogle. Using Hoogle you can search functions by various criteria and will often find functions which suit your needs.
Answer to old:
Use the isInfixOf function from Data.List to search for the pattern:
import Data.List (isInfixOf)
isInfixOf "1101" "1101000111001110" -- outputs true
It returns true if the first sequence exists in the second and false otherwise.
To read a file and get its contents use readFile:
contents <- readFile "filename.txt"
You will get the whole file as one string, which you can now perform standard functions on.
Outputting "Pattern found" should be trivial then.
Here is my datatype:
data Foo a = Value Integer
|Boo a
and I have a function for converting the Foo datatype to String:
showFoo::Show a=> Foo a -> String
showFoo (Value n) = show n
showFoo (Boo a) = show a
For example: showFoo (Value 10) becomes: "10", but for showFoo(Boo "S"), it becomes: "\"S\"" but I need only "S".
This boils down to the behaviour of show with strings.
show is designed to give machine-readable output, it's not a pretty-printer,
so it puts inverted commas round all strings. That way it can tell the
difference between 10 and "10" when it's reading them back in.
Your showFoo function is clearly not designed to be in the show family,
since it obliterates the Value and Boo tags, so using show isn't really what
you mean.
Possible solutions:
Give in, go the whole hog and derive Show.
If a is always a String, change your data type and don't use show.
Learn about type classes some more and define your own Showish class.
Use -XFlexibleInstances and -XOverlappingInstances to override
the instance for String, and don't use quotes.
Hack it by using init.tail.show $ a
That's just a result of you using GHCi and it showing the previous result. Try this in a compiled program or try running (in GHCi) putStrLn (showFoo (Boo "S")) and you will see that calling show on a string results in a single set of quotes.
Classic way to define Haskell functions is
f1 :: String -> Int
f1 ('-' : cs) -> f1 cs + 1
f1 _ = 0
I'm kinda unsatisfied writing function name at every line. Now I usually write in the following way, using pattern guards extension and consider it more readable and modification friendly:
f2 :: String -> Int
f2 s
| '-' : cs <- s = f2 cs + 1
| otherwise = 0
Do you think that second example is more readable, modifiable and elegant? What about generated code? (Haven't time to see desugared output yet, sorry!). What are cons? The only I see is extension usage.
Well, you could always write it like this:
f3 :: String -> Int
f3 s = case s of
('-' : cs) -> f3 cs + 1
_ -> 0
Which means the same thing as the f1 version. If the function has a lengthy or otherwise hard-to-read name, and you want to match against lots of patterns, this probably would be an improvement. For your example here I'd use the conventional syntax.
There's nothing wrong with your f2 version, as such, but it seems a slightly frivolous use of a syntactic GHC extension that's not common enough to assume everyone will be familiar with it. For personal code it's not a big deal, but I'd stick with the case expression for anything you expect other people to be reading.
I prefer writing function name when I am pattern matching on something as is shown in your case. I find it more readable.
I prefer using guards when I have some conditions on the function arguments, which helps avoiding if else, which I would have to use if I was to follow the first pattern.
So to answer your questions
Do you think that second example is more readable, modifiable and elegant?
No, I prefer the first one which is simple and readable. But more or less it depends on your personal taste.
What about generated code?
I dont think there will be any difference in the generated code. Both are just patternmatching.
What are cons?
Well patternguards are useful to patternmatch instead of using let or something more cleanly.
addLookup env var1 var2
| Just val1 <- lookup env var1
, Just val2 <- lookup env var2
= val1 + val2
Well the con is ofcourse you need to use an extension and also it is not Haskell98 (which you might not consider much of a con)
On the other hand for trivial pattern matching on function arguments I will just use the first method, which is simple and readable.
Am still new to Haskell, so apologize if there is an obvious answer to this...
I would like to make a function that splits up the all following lists of strings i.e. [String]:
["int x = 1", "y := x + 123"]
["int x= 1", "y:= x+123"]
["int x=1", "y:=x+123"]
All into the same string of strings i.e. [[String]]:
[["int", "x", "=", "1"], ["y", ":=", "x", "+", "123"]]
You can use map words.lines for the first [String].
But I do not know any really neat ways to also take into account the others - where you would be using the various sub-strings "=", ":=", "+" etc. to break up the main string.
Thank you for taking the time to enlighten me on Haskell :-)
The Prelude comes with a little-known handy function called lex, which is a lexer for Haskell expressions. These match the form you need.
lex :: String -> [(String,String)]
What a weird type though! The list is there for interfacing with a standard type of parser, but I'm pretty sure lex always returns either 1 or 0 elements (0 indicating a parse failure). The tuple is (token-lexed, rest-of-input), so lex only pulls off one token. So a simple way to lex a whole string would be:
lexStr :: String -> [String]
lexStr "" = []
lexStr s =
case lex s of
[(tok,rest)] -> tok : lexStr rest
[] -> error "Failed lex"
To appease the pedants, this code is in terrible form. An explicit call to error instead of returning a reasonable error using Maybe, assuming lex only returns 1 or 0 elements, etc. The code that does this reliably is about the same length, but is significantly more abstract, so I spared your beginner eyes.
I would take a look at parsec and build a simple grammar for parsing your strings.
how about using words .)
words :: String -> [String]
and words wont care for whitespaces..
words "Hello World"
= words "Hello World"
= ["Hello", "World"]