I (New to Haskell ) want to find if a word in line (of lines) is present or not. I saw few functions to achieve it like : elem, isInfixOf
Prelude DL> isInfixOf "new" "I am new to Haskell"
True
Prelude DL> elem "new" ["I am", "new to", "Haskell"]
False
How can I implement 'isInfixOf' on every string within list of strings.
If you expect to get true:
any (isInfixOf "new") ["I am", "new to", "Haskell too!"]
If you want a list of Bool:
map (isInfixOf "new") ["I am", "new to", "Haskell too!"]
You do this by mapping the isInfixOf function over a list of Strings like so:
ghci>> map (isInfixOf "new") ["I am", "new to", "Haskell"]
[False, True, False]
map evaluates the predicate for each element in the list.
Building from this, you can use other functions from Data.List to find out more about the list as a whole:
ghci>> any (isInfixOf "new") ["I am", "new to", "Haskell"]
True
ghci>> all (isInfixOf "new") ["I am", "new to", "Haskell"]
False
Related
Say I have a list of substrings [["hello", "how", "are", "you?"], ["I'm", "doing", "great"]] and I wanted to create a list of ["hello how are you?", "I'm doing great"] how would one go about this?
I've tried
sum(mylist, [])
>> ["hello", "how", "are", "you?", "I'm", "doing", "great"]
and also
new_list = []
for i in mylist:
new_list += i
>> ["hello", "how", "are", "you?", "I'm", "doing", "great"]
And neither seem to what I want it to do. I suspect that I need to join the subarrays first, and then append them maybe to a new list. Any thoughts or suggestions?
Once more the goal is to take:
[["hello", "how", "are", "you?"], ["I'm", "doing", "great"]]
and make it into:
["hello how are you?", "I'm doing great"]
One simple way to do it is use list comprehension:
nested_lists = [["hello", "how", "are", "you?"], ["I'm", "doing", "great"]]
joined_list = [' '.join(str_list) for str_list in nested_lists]
print(joined_list)
# Outputs ['hello how are you?', "I'm doing great"]
essentially list comprehension merges a loop and list construction in the same construct - see line 2.
my_list = [["hello", "how", "are", "you?"], ["I'm", "doing", "great"]]
new_list = []
for mini_list in my_list:
new_list.append(' '.join(mini_list)
This would therefore, take each item from that list which itself is a list and join them.
It will then append it to what I'm calling the new_list to give you the result you want.
Just mapping all sublists with ' '.join:
new_list = [*map(' '.join, mylist)]
Or one character shorter:
*new_list, = map(' '.join, mylist)
Let's say I have two lists of words called query and sentence. What I want to find is, for each pair of consecutive words in the query, a list of all the words between those two in the sentence. Also, if the first word of the query is not the first word of the sentence, the result should include a list with all the words in the sentence up to that one (and the same goes for the last word in the query).
So for example, if the query and the sentence looked like this:
query = ["like", "with"]
sentence = ["I", "like", "coffee", "with", "sugar", "and", "milk"]
then the result should be:
result = [["I"], ["coffee"],["sugar", "and", "milk"]]
However, there might be more than one way to make this match, depending on the sentence and query. For example:
query = ["bear", "my"]
sentence = ["I", "cannot", "bear", "when", "my", "bear", "leaves", "my", "house"]
In this case, there are many valid results:
result1 = [["I", "cannot"], ["when"], ["bear", "leaves", "my", "house"]]
result2 = [["I", "cannot"], ["when", "my", "bear", "leaves"], ["house"]]
result3 = [["I", "cannot", "bear", "when", "my"], ["leaves"], ["house"]]
So, what I need is a list of all the possible results for a given sentence and query. I've been trying to come up with a solution for a while now, but I can't work out how to find all possible combinations without making a mess of my code.
This is an exercise in non-determinism, which is modeled by the [] monad.
Start by writing a function
foo :: String -> [String] -> [([String], [String])]
that can split sentence into exactly two parts based on a given word. That is,
foo "bear" sentence == [
(["I", "cannot"], ["when", "my", "bear", "leaves", "my", "house"]),
(["I", "cannot", "bear", "when", "my"], ["leaves", "my", "house"]),
]
Given a list of split words, you recursively split the second list using the next split word.
do_it [] _ = []
do_it (q:qs) words = do
(x, y) <- foo q words
return (x : do_it qs words)
I have a dictionary were the keys are dictionaries encoded in bytestrings:
mydict = {
b'{"key 1": 3, "key 2": 6}': 'my first value',
b'{"key 1": 2, "key 2": 7}': 'my second value',
}
And I would like to know how to write the type hint.
In my head it would make sense something like:
from typing import Dict, ByteString
mydict: Dict[ByteString[Dict[str, int]], str] = {
b'{"key 1": 3, "key 2": 6}': 'my first value',
b'{"key 1": 2, "key 2": 7}': 'my second value',
}
But I get TypeError: typing.ByteString is not a generic class
Any suggestion?
It's simply Dict[Bytes, str] - Python doesn't understand the structure of the bytes.
In the same vein, the type of "6" is string, not "string that contains an integer", and "(1, 2)" is a simple string as well, not a string that contains a tuple of integers.
Maybe the closest thing to "typing a string" are template literal strings in TypeScript, but it's still not the same. A string is just a string - it can't be parametrised.
I have a function that given an Int returns a list of lists of Strings.
fetchParts :: Int -> [[String]]
This is what the output looks like
[["title", "some title"], ["rate", "2.4"], ["dist", "some string"], ["tr", "1"], ["td, "2"] ..]]
The length of the output can be variable. Only the first 3 lists can be present 100% of the time.
The later part of the list can be
["a", "1"], ["b", "2"] ..
or
["some", "1"], ["part", "2"], ["of", "3"] ..]
or
["ex1", "a"], ["ex2", "b"], ..]
or some other combination of strings.
And I want to add this output to a sqlite3 database file. I'm using HDBC and HDBC.Sqlite3 for this.
To add something to a database file I'm running functions like these
initialConnection <- connectSqlite3 "src/parts.db"
run initialConnection partsEntry []
commit initialConnection
disconnect initialConnection
where partsEntry is a simple SQL String like this
partsEntry = "INSERT INTO PARTSDATA ( title, rate, dist, ...) VALUES ( "some title", "2.4", "some string", ...)
where
( title, rate, dist, ...) are from head <$> fetchParts 1
and
("some title", "2.4", "some string" ...) are from last <$> fetchParts 1
The problem is say if "some" column doesn't exists, code will throw errors.
What I want to do is something like this
if column "abc" doesn't exists, add column "abc" and insert
"this" value at the current row
if column "abc" exists, just insert "this" value at the current row
But I'm not sure how to go about doing that.
I was able to solve the problem.
First use describeTable function from HDBC package. The function will return column names and type. If you just need the names like I did, this is what you can do
getColumnsInTable :: conn -> String -> IO [String]
getColumnsInTable conn tableName = do
d <- describeTable conn tableName
return $ fst <$> d
The return will have all the columns' names.
Scan through the list to see if it contains all the columns you wish. If it doesn't use a function like the following to alter the table, i.e. add a new column with INT type.
createNewColumn conn columnName = do
let stmt = "ALTER TABLE FantasyBooks ADD COLUMN " ++ columnName ++ " INT;"
run conn stmt []
I'm defining a TestList (HUnit) and want to spread the definition over multiple lines. I came to the following solution:
tests = TestList ([TestLabel "test1" test1] ++
[TestLabel "test2" test2] ++
[TestLabel "test3" test3] ++
[TestLabel "test4" test4] ++
[TestLabel "test5" test5])
Is the use of the ++ operator the proper way to do such things?
Are there better or more elegant ways to do this?
I'd write
tests = TestList
[ TestLabel "test1" test1
, TestLabel "test2" test2
, TestLabel "test3" test3
, TestLabel "test4" test4
, TestLabel "test5" test5 ]
There's still place for improvements for #ephemient variant: don't use TestLabel at all, use ~: shortcut:
tests = TestList
[ "test1" ~: test1
, "test2" ~: test2
, "test3" ~: test3
, "test4" ~: test4
, "test5" ~: test5 ]
Note that there are more operators to construct assertions: #?, #=?, #?=. See http://hunit.sourceforge.net/HUnit-1.0/Guide.html or http://hackage.haskell.org/package/HUnit for details. The shortcuts use priorities and type classes cleverly, so you will get much less parentheses noise at the cost of slightly worse error messages.
Maybe I'm missing something, but why not just commas? This doesn't seem particularly unlike a normal list.
tests = TestList ([TestLabel "test1" test1,
TestLabel "test2" test2,
TestLabel "test3" test3,
TestLabel "test4" test4,
TestLabel "test5" test5])