Haskell - Passing a function as an argument - function

so in haskell I have the following 2 functions made (they are just performing some math operations)
cubicQ :: Float -> Float -> Float -> Float
cubicQ a b c = (3*a*c - b**2) / (9*a**2)
cubicR :: Float -> Float -> Float -> Float -> Float
cubicR a b c d = (9*a*b*c - 27*(a**2)*d-2*b**3)
I am to make a third function cubicS that has a requirement that the function be of type Float -> Float -> Float and it calculates its output from q and r, which is the output for cubicQ and cubicR. How would I pass the functions cubicQ and cubicR as arguments q and r in cubicS? Below is what I have tried so far but I am stumped. Any help would be greatly appreciated.
cubicS q r = (r+ (q**3+r**2)**(1/2))**(1/3)
where q = (cubicQ a b c d)
r = (cubicR a b c)

try this:
cubicQ a b c = (3*a*c - b**2) / (9*a**2)
cubicR a b c d = (9*a*b*c - 27*(a**2)*d-2*b**3)
cubicS q r = (r+ (q**3+r**2)**(1/2))**(1/3)
f a b c d = cubicS (cubicQ a b c) (cubicR a b c d)
main = do print $ f 1 2 3 4
or:
cubicS a b c d = (r+ (q**3+r**2)**(1/2))**(1/3)
where q = cubicQ a b c
r = cubicR a b c d
or:
cubicS a b c d =
let q = cubicQ a b c
r = cubicR a b c d
in (r+ (q**3+r**2)**(1/2))**(1/3)
see:
cubicQ :: Float -> Float -> Float -> Float
cubicQ a b c = (3*a*c - b**2) / (9*a**2)
cubicR :: Float -> Float -> Float -> Float -> Float
cubicR a b c d = (9*a*b*c - 27*(a**2)*d-2*b**3)
cubicS :: Float -> Float -> Float -> Float -> Float
cubicS a b c d =
let q = cubicQ a b c
r = cubicR a b c d
in
(r+ (q**3+r**2)**(1/2))**(1/3)
main = do print $ cubicS 1.1 2.2 3.3 4.4
output:
9.736999e-2
and if you restricted to cubicS being cubicS: Float -> Float -> Float:
cubicQ a b c = (3*a*c - b**2) / (9*a**2)
cubicR a b c d = (9*a*b*c - 27*(a**2)*d-2*b**3)
cubicS q r = (r+ (q**3+r**2)**(1/2))**(1/3)
cureS a b c d = cubicS q r
where q = cubicQ a b c
r = cubicR a b c d
main = do print $ cureS 1.1 2.2 3.3 4.4

Related

Is there any query/code that can find common values in records?

Somebody can guide me (maybe Simple and fast query if there is or some fast code) to convert my CSV data file (with commas separation):
1,A,C,Z,F,G
2,G,Q,R,C,
3,Z,G,Q,
4,C,F,
5,O,P,
6,O,X,Y,J,
7,A,P,X,
I have this table with ~1,000,000 records
like these 7 records that you see (In real Database A,B,C,... are words in string), Records 1 and 2 are common in G and C value and 2,3 and 1,3 and ...
I want to sync records if they have at least two common value like Records 1 & 2,3,4 (but record 5,6,7 haven't at least 2 shared values with others) and generate a list like this:
1 A C Z F G Q R
2 G Q R C A Z F
3 Z G Q A C F R
4 C F A Z G Q R
5 O P
6 O X Y J
7 A P X
at the end we must have 4 same records if we sort data and one others without sync:
1 A C F G Q R Z
2 A C F G Q R Z
3 A C F G Q R Z
4 A C F G Q R Z
5 O P
6 J O X Y
7 A P X
Maybe I do not use good term for my meaning, please see:
1 A C Z F G
2 G Q R C
record 1 has C and G common with Record 2 now 1 has not R and Q thus we must have 1 A C Z F G + Q and R and Record 2 has not A,Z and F thus we must have: 2 G Q R C + A,Z and F thus at the end we have:
1 A C Z F G Q R
2 G Q R C A Z F
I need all records Respectively in the queue from top to bottom.
wrote a delphi code but it is so slow.
Someone suggest me this groovy code:
def f=[:]
new File('Data.csv').readLines().each{
def items=it.split(',')
def name
items.eachWithIndex { String entry, int i ->
if(i==0){
name=entry
}
else if(entry){
if(!f[entry])
f[entry]=[]
f[entry]<<name
}
}
}
f.findAll {it.value.size()>1}
It is very fast (because of using a map file I think), but It only finds the common values.
If you would go for a SQL solution, then that csv data could be
put in a normalized table with the data unfolded per ID & WORD.
Once you have that, it becomes a matter of self-joining that table.
And concatinate the words back together in alphabetic order.
SqlFiddle test here
Not sure how fast this method would be on a table with 1000k records though.
But it's an interesting puzzle.
Sample data:
DROP TABLE IF EXISTS test_words;
CREATE TABLE IF NOT EXISTS test_words (
id int unsigned NOT NULL PRIMARY KEY,
words varchar(60) NOT NULL
);
INSERT INTO test_words (id, words) VALUES
(1,'A C Z F G'),
(2,'G Q R C'),
(3,'Z G Q'),
(4,'C F'),
(5,'P O'),
(6,'O X Y J'),
(7,'A P X');
Tally table with numbers:
DROP TABLE IF EXISTS tmp_numbers;
CREATE TEMPORARY TABLE IF NOT EXISTS tmp_numbers (
n int unsigned NOT NULL PRIMARY KEY
);
INSERT INTO tmp_numbers (n) VALUES (1),(2),(3),(4),(5),(6),(7),(8),(9),(10);
Unfolding the words:
DROP TABLE IF EXISTS test_words_unfolded;
CREATE TABLE test_words_unfolded (
word varchar(10) NOT NULL,
id int unsigned NOT NULL,
PRIMARY KEY (word, id)
);
INSERT INTO test_words_unfolded (word, id)
SELECT DISTINCT SUBSTRING_INDEX(SUBSTRING_INDEX(t.words,' ', nr.n),' ',-1) as word, t.id
FROM test_words AS t
JOIN tmp_numbers AS nr
ON CHAR_LENGTH(t.words) - CHAR_LENGTH(REPLACE(t.words,' ','')) >= nr.n - 1
AND SUBSTRING_INDEX(SUBSTRING_INDEX(t.words,' ', nr.n),' ',-1) != '';
Result table:
DROP TABLE IF EXISTS test_result;
CREATE TABLE IF NOT EXISTS test_result (
id int unsigned NOT NULL PRIMARY KEY,
words varchar(60) NOT NULL
);
INSERT INTO test_result (id, words)
SELECT q.id, GROUP_CONCAT(DISTINCT t3.word ORDER BY t3.word ASC SEPARATOR ' ') as words
FROM
(
SELECT t1.id, t2.id as id2
FROM test_words_unfolded t1
JOIN test_words_unfolded t2 ON t1.word = t2.word
GROUP BY t1.id, t2.id
HAVING COUNT(*) > 1 OR t1.id = t2.id
) q
LEFT JOIN test_words_unfolded t3 ON t3.id = q.id2
GROUP BY q.id
ORDER BY q.id;
SELECT *
FROM test_result
ORDER BY id;
Result:
id words
-- -----
1 A C F G Q R Z
2 A C F G Q R Z
3 A C F G Q R Z
4 A C F G Z
5 O P
6 J O X Y
7 A P X
Extra
To mark the words that have been added, the query to fill the result table becomes a bit more complicated.
SELECT
q2.id,
GROUP_CONCAT(DISTINCT CASE WHEN q2.ori = 1 THEN q2.word ELSE CONCAT('[',q2.word,']') END ORDER BY q2.word ASC SEPARATOR ' ') as words
FROM
(
SELECT
q1.id, t3.word,
MAX(CASE WHEN q1.id = t3.id THEN 1 ELSE 0 END) as ori
FROM
(
SELECT
t1.id, t2.id as id2
FROM test_words_unfolded t1
JOIN test_words_unfolded t2 ON t1.word = t2.word
GROUP BY t1.id, t2.id
HAVING COUNT(*) > 1 OR t1.id = t2.id
) q1
LEFT JOIN test_words_unfolded t3 ON t3.id = q1.id2
GROUP BY q1.id, t3.word
) q2
GROUP BY q2.id
ORDER BY q2.id;
Result:
id words
-- -----
1 A C F G [Q] [R] Z
2 [A] C [F] G Q R [Z]
3 [A] [C] [F] G Q [R] Z
4 [A] C F [G] [Z]
5 O P
6 J O X Y
7 A P X
Additional experiment here

sql query for n rows plus another a row with id

I have a query, which return (say)10 rows
SELECT EL.ID AS ID ,EL.x AS x ,EL.y AS y,EL.z AS z,
EL.k AS k, EL.a AS a,
EL.b AS b ,EL.c AS c,EL.d AS d ,EL.e AS e ,
EL.f AS f,EL.g AS g
FROM MYTABLE EL
WHERE EL.x = '2004'
AND EL.y = 'FYY'
AND EL.z = 'test'
AND EL.a = 'INTC'
AND EL.b = 321593
Along with this i want to join the row of same table (MYTABLE) where id =4 (1 row)
Which is the most preferred way using SQL server syntax?
SELECT EL.ID AS ID ,EL.x AS x ,EL.y AS y,EL.z AS z,
EL.k AS k, EL.a AS a,
EL.b AS b ,EL.c AS c,EL.d AS d ,EL.e AS e ,
EL.f AS f,EL.g AS g
FROM MYTABLE EL
WHERE (EL.x = '2004'
AND EL.y = 'FYY'
AND EL.z = 'test'
AND EL.a = 'INTC'
AND EL.b = 321593)
OR (EL.ID = 4)

Receiving data with spaces, thru sockets

I'm using C++ with QT4 for this. And when I try to send large html files(in this case, 8kb), the process of sending and receiving work well. But the file received come with spaces between each character of the html file. Here an example, the file is sent like this:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd">
<html><head><meta name="qrichtext" content="1" /><style type="text/css">
p, li { white-space: pre-wrap; }
</style></head><body style=" font-family:'MS Shell Dlg 2'; font-size:8.25pt; font-weight:400; font-style:normal;">
<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">a</p></body></html>
and it's received, like this:
¼ < ! D O C T Y P E H T M L P U B L I C " - / / W 3 C / / D T D H T M L 4 . 0 / / E N " " h t t p : / / w w w . w 3 . o r g / T R / R E C - h t m l 4 0 / s t r i c t . d t d " >
< h t m l > < h e a d > < m e t a n a m e = " q r i c h t e x t " c o n t e n t = " 1 " / > < s t y l e t y p e = " t e x t / c s s " >
p , l i { w h i t e - s p a c e : p r e - w r a p ; }
< / s t y l e > < / h e a d > < b o d y s t y l e = " f o n t - f a m i l y : ' M S S h e l l D l g 2 ' ; f o n t - s i z e : 8 . 2 5 p t ; f o n t - w e i g h t : 4 0 0 ; f o n t - s t y l e : n o r m a l ; " >
< p s t y l e = " - q t - p a r a g r a p h - t y p e : e m p t y ; m a r g i n - t o p : 0 p x ; m a r g i n - b o t t o m : 0 p x ; m a r g i n - l e f t : 0 p x ; m a r g i n - r i g h t : 0 p x ; - q t - b l o c k - i n d e n t : 0 ; t e x t - i n d e n t : 0 p x ; " > < / p > < / b o d y > < / h t m l >
the code i'm using for sending and receiving:
Sending code:
qDebug() << "Connected. Sending file to the server"; QString text = ui->QuestHtmlText->toPlainText();
if(text.length() < 1024)
{
QByteArray block;
QDataStream out(&block, QIODevice::WriteOnly);
out << quint16(0) << QUESTION_HTML;
out << text;
out.device()->seek(0);
out << quint16(block.size() - sizeof(quint16));
qDebug() << "Block size: " << block.size();
socket.write(block);
return;
}
for(int i = 0; i < text.length(); i+=1024)
{
QByteArray block;
QDataStream out(&block, QIODevice::WriteOnly);
out << quint16(0) << QUESTION_HTML;
if((text.length() - i) > 1024)
out << text.mid(i, i+1024);
else
out << text.right(1024 - i);
out.device()->seek(0);
out << quint16(block.size() - sizeof(quint16));
qDebug() << "Block size: " << block.size();
socket.write(block);
}
Receiving code:
qDebug() << "Writing File";
QDataStream in(this);
QString temp = "Teste.html", text;
QFile myFile(".//Questions//" + temp);
myFile.open(QIODevice::WriteOnly);
QDataStream out(&myFile);
while(!in.atEnd())
{
in >> text;
out << text;
}
I did opened a post before, here: Sending data through socket spaces, receiving with spaces
People stopped helping me out. By the way, i didnt feel like my question was completly answered. So I opened another post.
I also looked in the FAQ section to see what should I do in this case. But with no sucess.
Anyway, my question now is: should I remove the quint16? what should I use to determine the size of the incoming packet then ?
Thanks, and I'm sorry about the mistakes I may have made.
The stuff you are getting back in the file is not your original text, but QString serialization form, which is unsuprisingly UTF-16. If you want your text back, read the input QDataStream back to QString and save that into file.
While prefixing your data with a length is generally a good idea, it is absolutely redundant with QString >> QDataStream. Read up something here or here. Moreover you have developed a mind boggingly obfuscated way which i suspect is doing nothing. QByteArray is not implementing QIODevice (indeed, why it should) so your out.device()->seek() is a base virtual implementation, empty and just returning true. I won't be surprised if your length "header" is found at the end of your serialization dump file.
Edit: i think that your html transport might start working correctly only by leaving out the confused quint operation completely and use out QTextStream instead of QByteStream.
I posted the solution for my case in the other post.
Thanks you all for the attention

Sending data through socket spaces, receiving with spaces

I'm using C++ with QT4 for this. And when I try to send large html files(in this case, 8kb), the process of sending and receiving work well. But the file received come with spaces between each character of the html file. Here an example,
the file is sent like this:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd">
<html><head><meta name="qrichtext" content="1" /><style type="text/css">
p, li { white-space: pre-wrap; }
</style></head><body style=" font-family:'MS Shell Dlg 2'; font-size:8.25pt; font-weight:400; font-style:normal;">
<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">a</p></body></html>
and it's received, like this:
¼ < ! D O C T Y P E H T M L P U B L I C " - / / W 3 C / / D T D H T M L 4 . 0 / / E N " " h t t p : / / w w w . w 3 . o r g / T R / R E C - h t m l 4 0 / s t r i c t . d t d " >
< h t m l > < h e a d > < m e t a n a m e = " q r i c h t e x t " c o n t e n t = " 1 " / > < s t y l e t y p e = " t e x t / c s s " >
p , l i { w h i t e - s p a c e : p r e - w r a p ; }
< / s t y l e > < / h e a d > < b o d y s t y l e = " f o n t - f a m i l y : ' M S S h e l l D l g 2 ' ; f o n t - s i z e : 8 . 2 5 p t ; f o n t - w e i g h t : 4 0 0 ; f o n t - s t y l e : n o r m a l ; " >
< p s t y l e = " - q t - p a r a g r a p h - t y p e : e m p t y ; m a r g i n - t o p : 0 p x ; m a r g i n - b o t t o m : 0 p x ; m a r g i n - l e f t : 0 p x ; m a r g i n - r i g h t : 0 p x ; - q t - b l o c k - i n d e n t : 0 ; t e x t - i n d e n t : 0 p x ; " > < / p > < / b o d y > < / h t m l >
the code i'm using for sending and receiving:
Sending code:
qDebug() << "Connected. Sending file to the server";
QString text = ui->QuestHtmlText->toPlainText();
if(text.length() < 1024)
{
QByteArray block;
QDataStream out(&block, QIODevice::WriteOnly);
out << quint16(0) << QUESTION_HTML;
out << text;
out.device()->seek(0);
out << quint16(block.size() - sizeof(quint16));
qDebug() << "Block size: " << block.size();
socket.write(block);
return;
}
for(int i = 0; i < text.length(); i+=1024)
{
QByteArray block;
QDataStream out(&block, QIODevice::WriteOnly);
out << quint16(0) << QUESTION_HTML;
if((text.length() - i) > 1024)
out << text.mid(i, i+1024);
else
out << text.right(1024 - i);
out.device()->seek(0);
out << quint16(block.size() - sizeof(quint16));
qDebug() << "Block size: " << block.size();
socket.write(block);
}
Receiving code:
qDebug() << "Writing File";
QDataStream in(this);
QString temp = "Teste.html", text;
QFile myFile(".//Questions//" + temp);
myFile.open(QIODevice::WriteOnly);
QDataStream out(&myFile);
while(!in.atEnd())
{
in >> text;
out << text;
}
#Eugen i suspect the quint16 is either not written at all or is at the end of the file. Read below.
#Patrick don't repost only because you feel like not being served fast enough. Stackowerflow is not a hotline.
The stuff you are getting back in the file is not your original text, but QString serialization form, which is unsuprisingly UTF-16. If you want your text back, read the input QDataStream back to QString and save that into file.
While prefixing your data with a length is generally a good idea, it is absolutely redundant with QString >> QDataStream. Read up something here or here. Moreover you have developed a mind boggingly obfuscated way which i suspect is doing nothing. QByteArray is not implementing QIODevice (indeed, why it should) so your out.device()->seek() is a base virtual implementation, empty and just returning true. I won't be surprised if your length "header" is found at the end of your serialization dump file.
Edit: i think that your html transport might start working correctly only by leaving out the confused quint operation completely and use out QTextStream instead of QByteStream.
I bet there are not spaces between characters (but 0s) & you get the extra chars due to your use of quint16.
I solved the problem writing it to a file and getting this file to a QByteArray, and sending the QbyteArray entirely to the socket.

What is this type of table called?

SELECT
*
FROM
(
SELECT a, b, c
FROM ABC
WHERE f = '1'
LEFT JOIN
SELECT v, n, m
FROM VBN
WHERE g = '1'
ON (v = a)
);
I am trying to select from a table is is built on the fly from conditions, what is this kind of table called? Live table?
You can call it as subquery.
If you wanted to apply a name to this subquery you can use an alias or by creating a view.
SELECT
aJoinedTable.*
FROM
(
SELECT a, b, c
FROM ABC
WHERE f = '1'
LEFT JOIN
SELECT v, n, m
FROM VBN
WHERE g = '1'
ON (v = a)
) as aJoinedTable;