<div dir="ltr"><div dir="ltr">On Fri, Apr 12, 2019 at 12:42 AM Guy-Laurent Subri <<a href="mailto:guy-laurent@subri.ch">guy-laurent@subri.ch</a>> wrote:</div><div class="gmail_quote"><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">
I've noticed that if I write<br>
'''<br>
instance ToField Table where<br>
toField (Table t) = SQLText t<br>
'''<br>
<br>
I have no error and it compiles. I don't get it, what is 'toField'<br>
supposed to receive except a Table?<br></blockquote><div><br></div><div>Haskell does not automatically "convert" types. If something wants a Text, it will not accept a Table, even though that Table is just a wrapper around a Text. You must unwrap it to get the Text inside, which is what the (Table t) pattern is doing: matches a Table by its constructor, and gives you the contained Text bound to "t".</div><div><br></div><div>This is somewhat more obvious when you have a type with multiple fields, or with multiple constructors, since pattern matching then lets you access all the fields, and you can have multiple patterns matching different constructors.</div><div><br></div><div> data Foo = Foo Int Text</div><div> someFoo (Foo i t) = -- do something with the Int i and Text t here</div><div><br></div><div> data Foo = FooI Int | FooT Text</div><div> someFoo (FooI i) = -- do something with the Int i here</div><div> someFoo (FooT t) = -- do something with the Text t here</div><div><br></div><div>(You can of course also combine them, multiple constructors each with zero or more fields.)</div><div><br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">2. My second question is concerning the initDB function. If I write it<br>
that way, the code compiles, but I get an error during execution:<br>
<br>
bkmrk: SQLite3 returned ErrorError while attempting to perform prepare<br>
"CREATE TABLE IF NOT EXISTS :table (url TEXT, tags TEXT, date<br>
INTEGER)": near ":table": syntax error<br>
<br>
I don't understand what is wrong with the code and I doubt that my query<br>
is wrong because everything works with the last code snippet I wrote<br>
(see question #3).<br></blockquote><div><br></div><div>In general, you can't use that kind of substitution with SQL Data Definition Language (e.g. CREATE TABLE), nor is it generally usable to replace table or column names, only values. You need to concatenate the actual table name into the command, not a SQL string-like value nor an embedded SQL placeholder.</div><div><br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">3. Trying to get around the error I've noticed a few things. If I try to<br>
write this instead:<br>
<br>
'''<br>
initDB :: FilePath -> Table -> IO BookmarkDB<br>
initDB fp table = do<br>
let query = Query ("CREATE TABLE IF NOT EXISTS " <> table<br>
<> " (url TEXT, tags TEXT, date INTEGER)")<br>
conn <- open fp<br>
execute_ conn query<br>
return $ BookmarkDB conn table<br>
'''<br>
<br>
it doesn't compile because table is of type Table and not<br>
Data.Text.Internal.Text, which I get, but I don't know what is the<br>
Haskell way of resolving this.<br></blockquote><div><br></div><div>Same as your first question:</div><div><br></div><div> initDB fp t@(Table table) = do -- which unwraps the Table and gives you the Text within it as "table".</div><div><br></div><div>But you also need the actual Table value, since you use it in the last line of your function, so you also need the as-pattern.</div><div><br></div></div>-- <br><div dir="ltr" class="gmail_signature"><div dir="ltr"><div><div dir="ltr"><div>brandon s allbery kf8nh</div><div><a href="mailto:allbery.b@gmail.com" target="_blank">allbery.b@gmail.com</a></div></div></div></div></div></div>