couldn't match type 'ByteString o0 m0 Value' Vs 'ByteString Data.Void.Void IO Value' - json

I am trying the haskell-json-service. When I run the code, it throws error here:
app req sendResponse = handle (sendResponse . invalidJson) $ do
value <- sourceRequestBody req $$ sinkParser json
newValue <- liftIO $ modValue value
sendResponse $ responseLBS
status200
[("Content-Type", "application/json")]
$ encode newValue
Error is,
Couldn't match type ‘conduit-1.2.4:Data.Conduit.Internal.Conduit.ConduitM
ByteString o0 m0 Value’
with ‘conduit-1.2.4.1:Data.Conduit.Internal.Conduit.ConduitM
ByteString Data.Void.Void IO Value’
NB: ‘conduit-1.2.4:Data.Conduit.Internal.Conduit.ConduitM’
is defined in ‘Data.Conduit.Internal.Conduit’
in package ‘conduit-1.2.4’
‘conduit-1.2.4.1:Data.Conduit.Internal.Conduit.ConduitM’
is defined in ‘Data.Conduit.Internal.Conduit’
in package ‘conduit-1.2.4.1’
Expected type: conduit-1.2.4.1:Data.Conduit.Internal.Conduit.Sink
ByteString IO Value
Actual type: conduit-1.2.4:Data.Conduit.Internal.Conduit.ConduitM
ByteString o0 m0 Value
In the second argument of ‘($$)’, namely ‘sinkParser json’
In a stmt of a 'do' block:
value <- sourceRequestBody req $$ sinkParser json
What does double dollar do? And what is this type - ByteString o0 m0 Value?

This appears to be the problem:
conduit-1.2.4:...
conduit-1.2.4.1:...
Your code is using a ByteString type from two different versions of the conduit library. From the point of view of GHC, these two types are unrelated: for instance, you can not pass the first type to a library function which expects the second one.
A cause for this could be using a library X which was compiled against the "old" conduit and a library Y which instead was compiled against the newer version. If your program imports X and Y, you will get in trouble when passing bytestrings from X to Y or vice versa. I have no idea about what X or Y actually are.
Maybe you can recompile X or Y so that they use the same version of conduit.

Related

Easiest way to enter a JSON literal in Haskell ghci

I'm testing out some functions in ghci before I put them into a project, and I'm straining to find the simplest way to enter json literals in the ghci without a ton of boilerplate
For example, I'd like to try out:
myFuncThatTakesAJson
on inputs
x = {}
y = {"a": 1}
But when I try entering these:
import Text.JSON
Prelude> x = parseJSON "{}"
Prelude> y = parseJSON "{'a' : 1}"
I see errors like:
<interactive>:17:5: error:
Variable not in scope: parseJSON :: [Char] -> t
y = fromJSON "{'a' : 1}"
<interactive>:20:5: error:
Data constructor not in scope: FromJSON :: [Char] -> t
Is there any way to allow json objects to be entered as strings without defining full data types with custom FromJSON instances?
There sure is! The type of a raw JSON value is Value. With that in mind, here's a couple of ways of constructing a Value in GHCi:
with parseJSON: since Value also has a FromJSON instance, you can use decode :: FromJSON a => ByteString -> Maybe a on it. Note that aeson is encouraging you to use ByteString instead of the inefficient default String. You can gloss over this detail by making string literals be overloaded by turning on -XOverloadedStrings:
ghci> import Data.ByteString
ghci> import Data.Aeson
ghci> :set -XOverloadedStrings
ghci> x = decode "{}" :: Maybe Value
x :: Maybe Value
ghci> y = decode "{\"a\" : 1}" :: Maybe Value -- note: single quotes won't work
y :: Maybe Value
with quasiquotes: you can also make use of the aesonQQ quasiquoter to get compile time JSON literals (this won't matter much in the REPL, beyond looking nicer, but in real code it means no actual parsing at runtime):
ghci> import Data.Aeson.QQ.Simple
ghci> :set -XQuasiQuotes
ghci> x = [aesonQQ| {} |]
x :: Value
ghci> y = [aesonQQ| {"a" : 1} |]
y :: Value

Get Column in Haskell CSV and infer the column type

I'm exploring a csv file in an interactive ghci session (in a jupyter notebook):
import Text.CSV
import Data.List
import Data.Maybe
dat <- parseCSVFromFile "/home/user/data.csv"
headers = head dat
records = tail dat
-- define a way to get a particular row by index
indexRow :: [[Field]] -> Int -> [Field]
indexRow csv index = csv !! index
indexRow records 1
-- this works!
-- Now, define a way to get a particular column by index
indexField :: [[Field]] -> Int -> [Field]
indexField records index = map (\x -> x !! index) records
While this works if I know in advance the type of column 3:
map (\x -> read x :: Double) $ indexField records 3
How can I ask read to infer what the type might be when for example my columns could contain strings or num? I'd like it to try for me, but:
map read $ indexField records 3
fails with
Prelude.read: no parse
I don't care whether they are string or num, I just need that they are all the same and I am failing to find a way to specify that generally with the read function at least.
Weirdly, if I define a mean function like so:
mean :: Fractional a => [a] -> Maybe a
mean [] = Nothing
mean [x] = Just x
mean xs = Just (sum(xs) / (fromIntegral (length xs)))
This works:
mean $ map read $ indexField records 2
Just 13.501359655240003
But without the mean, this still fails:
map read $ indexField records 2
Prelude.read: no parse
Unfortunately, read is at the end of its wits when it comes to situations like this. Let's revisit read:
read :: Read a => String -> a
As you can see, a doesn't depend on the input, but solely on the output, and therefore of the context of our function. If you use read a + read b, then the additional Num context will limit the types to Integer or Double due to default rules. Let's see it in action:
> :set +t
> read "1234"
*** Exception: Prelude.read: no parse
> read "1234" + read "1234"
2468
it :: (Num a, Read a) => a
Ok, a is still not helpful. Is there any type that we can read without additional context? Sure, unit:
> read "()"
()
it :: Read a => a
That's still not helpful at all, so let's enable the monomorphism restriction:
> :set -XMonomorphismRestriction
> read "1234" + read "1234"
2468
it :: Integer
Aha. In the end, we had an Integer. Due to +, we had to decide on a type. Now, with the MonomorphismRestriction enabled, what happens on read "1234" without additional context?
> read "1234"
<interactive>:20:1
No instance for (Read a0) arising from a use of 'read'
The type variable 'a0' is ambiguous
Now GHCi doesn't pick any (default) type and forces you to chose one. Which makes the underlying error much more clear.
So how do we fix this? As CSV can contain arbitrary fields at run-time and all types are determined statically, we have to cheat by introducing something like
data CSVField = CSVString String | CSVNumber Double | CSVUnknown
and then write
parse :: Field -> CSVField
After all, our type needs to cover all possible fields.
However, in your case, we can just restrict read's type:
myRead :: String -> Double
myRead = read
But that's not wise, as we can still end up with errors if the column doesn't contain Doubles to begin with. So instead, let's use readMaybe and mapM:
columnAsNumbers :: [Field] -> Maybe [Double]
columnAsNumbers = mapM readMaybe
That way, the type is fixed, and we're forced to check whether we have Just something or Nothing:
mean <$> columnAsNumbers (indexFields records 2)
If you find yourself often using columnAsNumbers create an operator, though:
(!!$) :: [[Field]] -> Maybe [Double]
records !!$ index = columnAsNumbers $ indexFields records index

How to handle variability of JSON objects in Haskell?

Some REST service has variable returning JSONs, for example some fields can appear or disappear depending on the parameters of the request, the structure itself may change, nesting, etc.
So, this leads to avalanche-type growth in the number of types (along with FromJSON instances). Options are to:
try to make a lot of fields under Maybe (but this does not help very much with the variability in structure)
to introduce a lot of types
to create different phantom types (actually no big difference with prev.)
The 1. has drawback that if your call with some fixed parameters always returns good knows fields, you have to handle Nothing cases too, code becomes more complex. The 2. and 3. is tiring.
What is the most simple/convenient way to handle such variability in Haskell (if you use Aeson, sure, another option is to avoid Aeson usage)?
A possible solution to the existing/non-existing fields problem using type-level computation.
Some required extensions and imports:
{-# LANGUAGE DeriveGeneric, ScopedTypeVariables, DataKinds, KindSignatures,
TypeApplications, TypeFamilies, TypeOperators, FlexibleContexts #-}
import Data.Aeson
import Data.Proxy
import GHC.Generics
import GHC.TypeLits
Here's a data type (to be used promoted) that indicates if some field is absent or present. Also a type family that maps absent types to ():
data Presence = Present
| Absent
type family Encode p v :: * where
Encode Present v = v
Encode Absent v = ()
Now we can define a parameterized record containing all possible fields, like this:
data Foo (a :: Presence)
(b :: Presence)
(c :: Presence) = Foo {
field1 :: Encode a Int,
field2 :: Encode b Bool,
field3 :: Encode c Char
} deriving Generic
instance (FromJSON (Encode a Int),
FromJSON (Encode b Bool),
FromJSON (Encode c Char)) => FromJSON (Foo a b c)
One problem: writing the full type for each combination of occurrences/absences would be tedious, especially if only a few fields are present each time. But perhaps we could define an auxiliary type synonym FooWith that let us mention only those fields that are present:
type family Mentioned (ns :: [Symbol]) (n :: Symbol) :: Presence where
Mentioned '[] _ = Absent
Mentioned (n ': _) n = Present
Mentioned (_ ': ns) n = Mentioned ns n
-- the field names are repeated as symbols, how to avoid this?
type FooWith (ns :: [Symbol]) = Foo (Mentioned ns "field1")
(Mentioned ns "field2")
(Mentioned ns "field3")
Example of use:
ghci> :kind! FooWith '["field2","field3"]
FooWith '["field2","field3"] :: * = Foo 'Absent 'Present 'Present
Another problem: for each request, we must repeat the list of required fields two times: one in the URL ("fields=a,b,c...") and another in the expected type. It would be better to have a single source of truth.
We can deduce the term-level list of fields to be added to the URL from the type-level list of fields, by using an auxiliary type class Demote:
class Demote (ns :: [Symbol]) where
demote :: Proxy ns -> [String]
instance Demote '[] where
demote _ = []
instance (KnownSymbol n, Demote ns) => Demote (n ': ns) where
demote _ = symbolVal (Proxy #n) : demote (Proxy #ns)
For example:
ghci> demote (Proxy #["field2","field3"])
["field2","field3"]

Aeson: "when expecting a string, encountered an object instead"

I'm fairly new to Haskell, so I meant be missing something simple. Right now, I'm just trying to read in some JSON from stdin and get the AST back as a proof of concept.
module JSONStuff where
import qualified Data.Aeson as JSON
import qualified Data.ByteString.Lazy.Char8 as Char
main :: IO ()
main = do
input <- Char.getContents
case JSON.eitherDecode input of
Left err -> putStrLn $ "Bad JSON: " ++ err
Right value -> do
putStrLn "Got:"
putStrLn value
I have this JSON fragment (which JSONLint says is ok):
{
"foo": 123
}
When I the program with that input, I get:
$ cat examples/object.json | runhaskell Main.hs
Bad JSON: when expecting a String, encountered Object instead
When I test on a file that's and empty array, it says it "encountered Array instead".
So I'm guessing I'm missing some kind of conversion step in here, or I'm reading from stdin incorrectly. What do you think?
The problem is this line:
putStrLn value
Since the type of putStrLn is String -> IO (), the type of value is inferred as String, so the FromJSON instance for strings will be used, which will only decode strings, since that's what the type can handle. To decode something else, you need a different type for value.
Try
print (value :: JSON.Object)
if you expect an object, or
print (value :: JSON.Value)
if any JSON value is acceptable.
Note the use of print instead of putStrLn. print accepts any type with a Show instance, so unlike putStrLn it does not force its argument to be a string. Also note that print value without the type annotation would not work in this example, as there would not be enough information for the compiler to deduce which type value should have, and therefore which Show and FromJSON instances to use.

haskell word searching program development

hello I am making some word searching program
for example
when "text.txt" file contains "foo foos foor fo.. foo fool"
and search "foo"
then only number 2 printed
and search again and again
but I am haskell beginner
my code is here
:module +Text.Regex.Posix
putStrLn "type text file"
filepath <- getLine
data <- readFile filepath
--1. this makes <interactive>:1:1: parse error on input `data' how to fix it?
parsedData =~ "[^- \".,\n]+" :: [[String]]
--2. I want to make function and call it again and again
searchingFunc = do putStrLn "search for ..."
search <- getLine
result <- map (\each -> if each == search then count = count + 1) data
putStrLn result
searchingFunc
}
sorry for very very poor code
my development environment is Windows XP SP3 WinGhci 1.0.2
I started the haskell several hours ago sorry
thank you very much for reading!
edit: here's original scheme code
thanks!
#lang scheme/gui
(define count 0)
(define (search str)
(set! count 0)
(map (λ (each) (when (equal? str each) (set! count (+ count 1)))) data)
(send msg set-label (format "~a Found" count)))
(define path (get-file))
(define port (open-input-file path))
(define data '())
(define (loop [line (read-line port)])
(when (not (eof-object? line))
(set! data (append data
(regexp-match* #rx"[^- \".,\n]+" line)))
(loop)))
(loop)
(define (cb-txt t e) (search (send t get-value)))
(define f (new frame% (label "text search") (min-width 300)))
(define txt (new text-field% (label "type here to search") (parent f) (callback (λ (t e) (cb-txt t e)))))
(define msg (new message% (label "0Found ") (parent f)))
(send f show #t)
I should start by iterating what everyone would (and should) say: Start with a book like Real World Haskell! That said, I'll post a quick walkthrough of code that compiles, and hopefully does something close to what you originally intended. Comments are inline, and hopefully should illustrate some of the shortcomings of your approach.
import Text.Regex.Posix
-- Let's start by wrapping your first attempt into a 'Monadic Action'
-- IO is a monad, and hence we can sequence 'actions' (read as: functions)
-- together using do-notation.
attemptOne :: IO [[String]]
-- ^ type declaration of the function 'attemptOne'
-- read as: function returning value having type 'IO [[String]]'
attemptOne = do
putStrLn "type text file"
filePath <- getLine
fileData <- readFile filePath
putStrLn fileData
let parsed = fileData =~ "[^- \".,\n]+" :: [[String]]
-- ^ this form of let syntax allows us to declare that
-- 'wherever there is a use of the left-hand-side, we can
-- substitute it for the right-hand-side and get equivalent
-- results.
putStrLn ("The data after running the regex: " ++ concatMap concat parsed)
return parsed
-- ^ return is a monadic action that 'lifts' a value
-- into the encapsulating monad (in this case, the 'IO' Monad).
-- Here we show that given a search term (a String), and a body of text to
-- search in, we can return the frequency of occurrence of the term within the
-- text.
searchingFunc :: String -> [String] -> Int
searchingFunc term
= length . filter predicate
where
predicate = (==)term
-- ^ we use function composition (.) to create a new function from two
-- existing ones:
-- filter (drop any elements of a list that don't satisfy
-- our predicate)
-- length: return the size of the list
-- Here we build a wrapper-function that allows us to run our 'pure'
-- searchingFunc on an input of the form returned by 'attemptOne'.
runSearchingFunc :: String -> [[String]] -> [Int]
runSearchingFunc term parsedData
= map (searchingFunc term) parsedData
-- Here's an example of piecing everything together with IO actions
main :: IO ()
main = do
results <- attemptOne
-- ^ run our attemptOne function (representing IO actions)
-- and save the result
let searchResults = runSearchingFunc "foo" results
-- ^ us a 'let' binding to state that searchResults is
-- equivalent to running 'runSearchingFunc'
print searchResults
-- ^ run the IO action that prints searchResults
print (runSearchingFunc "foo" results)
-- ^ run the IO action that prints the 'definition'
-- of 'searchResults'; i.e. the above two IO actions
-- are equivalent.
return ()
-- as before, lift a value into the encapsulating Monad;
-- this time, we're lifting a value corresponding to 'null/void'.
To load this code, save it into a .hs file (I saved it into 'temp.hs'), and run the following from ghci. Note: the file 'f' contains a few input words:
*Main Text.Regex.Posix> :l temp.hs
[1 of 1] Compiling Main ( temp.hs, interpreted )
Ok, modules loaded: Main.
*Main Text.Regex.Posix> main
type text file
f
foo foos foor fo foo foo
The data after running the regex: foofoosfoorfofoofoo
[1,0,0,0,1,1]
[1,0,0,0,1,1]
There is a lot going on here, from do notation to Monadic actions, 'let' bindings to the distinction between pure and impure functions/values. I can't stress the value of learning the fundamentals from a good book!
Here is what I made of it. It doesn't does any error checking and is as basic as possible.
import Text.Regex.Posix ((=~))
import Control.Monad (when)
import Text.Printf (printf)
-- Calculates the number of matching words
matchWord :: String -> String -> Int
matchWord file word = length . filter (== word) . concat $ file =~ "[^- \".,\n]+"
getInputFile :: IO String
getInputFile = do putStrLn "Enter the file to search through:"
path <- getLine
readFile path -- Attention! No error checking here
repl :: String -> IO ()
repl file = do putStrLn "Enter word to search for (empty for exit):"
word <- getLine
when (word /= "") $
do print $ matchWord file word
repl file
main :: IO ()
main = do file <- getInputFile
repl file
Please start step by step. IO in Haskell is hard, so you shouldn't start with file manipulation. I would suggest to write a function that works properly on a given String. That way you can learn about syntax, pattern matching, list manipulation (maps, folds) and recursion without beeing distracted by the do notation (which kinda looks imperative, but isn't, and really needs a deeper understanding).
You should check out Learn you a Haskell or Real World Haskell to get a sound foundation. What you do now is just stumbling in the dark - which may work if you learn languages that are similar to the ones you know, but definitely not for Haskell.