I'm trying to write a simple Fibonacci web server using WAI but I just can't figure out the types. This code is the essence of what I want to do, but it's broken. The getQueryArg function returns a Maybe ByteString and I want to use that in my fibHandler function.
How do I correctly handle the Maybe in my fibHandler?
How do I call putStrLn on a Maybe? I'm trying fmap but I can't seem to get it right.
{-# LANGUAGE OverloadedStrings #-}
import Network.Wai
import Network.HTTP.Types
import Network.Wai.Handler.Warp (run)
import Data.ByteString.Lazy.Char8 () -- Just for an orphan instance
import Control.Monad.IO.Class (liftIO)
import Data.Conduit
import Data.String.Utils
import Data.ByteString as BS (ByteString, putStrLn)
import Data.ByteString.Char8 as B (unpack)
import Data.Text as T (intercalate, pack, unpack)
app :: Application
app req
| rawPathInfo req == "/fib" = fibHandler req
| otherwise = notFoundHandler
fibHandler :: Request -> ResourceT IO Response
fibHandler req = do
let nStr = getQueryArg (queryString req) "n"
fmap (liftIO . BS.putStrLn) n
let n = read nStr
return $ responseLBS
status200
[("Content-Type", "text/plain")]
(show $ fib n)
fib :: Int -> Int
fib n = foldl (*) 1 [1..n]
getQueryArg :: Query -> BS.ByteString -> Maybe BS.ByteString
getQueryArg [] key = Nothing
getQueryArg ((k,v):qs) key
| k == key = Just v
| otherwise = getQueryArg qs key
notFoundHandler :: ResourceT IO Response
notFoundHandler = return $ responseLBS
status404
[("Content-Type", "text/plain")]
"Not found"
main :: IO ()
main = do
BS.putStrLn $ "http://localhost:8080/"
run 8080 $ app
[Update: a working copy of this code is here: https://gist.github.com/3145317]
The simplest thing to do with Maybe values is to use case.
case getQueryArg foo bar of
Nothing -> {- something went wrong, write some code to report an error -}
Just x -> {- everything went okay, and x is the result of the successful computation -}
Once you've done this a couple dozen times, you can graduate to the shorthand versions:
maybe ({- went wrong -}) (\x -> {- successful x -}) (getQueryArg foo bar)
fromMaybe {- default value -} (getQueryArg foo bar)
traverse_ B.putStrLn (getQueryArg foo bar) -- this trick is a personal favorite
Related
I am trying to iterate through a stream in order to print the content.
type 'a stream = Nil | Cons of 'a * 'a stream thunk and 'a thunk = unit -> 'a
This is where my function is called
|> iter_stream ~f:(fun (f,c,l) -> printf "%s %s %s\n" f c l)
And this is the type
let rec iter_stream st ~f
(* val iter_stream : 'a stream -> ('a -> unit) -> unit *)
I can't seem to find any examples on how to implement it. The only idea I have is to think about it like a list which is obviously wrong since I get type errors.
let rec iter_stream st ~f =
match st with
| None -> ()
| Some(x, st') -> f x; iter_stream st' ~f
Your stream is extremely similar to a list, except that you need to call a function to get the tail of the list.
Your proposed code has many flaws. The main two flaws that I see are:
You're using the constructors None and Some while a stream has constructors Nil and Cons.
You're not calling a function to get the tail of the stream. Note that in Cons (a, b), b is a "stream thunk", i.e., it's a function that you can call to get a stream.
(Perhaps these are the only two flaws :-)
I hope this helps.
I am trying to learn Purescript. A lot of the literature is focused on abstract concepts, for which the language is obviously very well suited; however, it is difficult to bring those concepts home to something familiar.
In order to better understand Purescript, and partly to challenge Purescript on a procedural task, I want to rewrite a very simple Node script written in Typescript.
The script reads some input from the command line, calls an async function that hydrates a (server-side) redux store, and then prints some data to the console.
import { store } from '../server/store'
import { deep, log, red } from '../src/io'
import { isRehydrated } from './isRehydrated'
async function readRecord(dbName: string, tableName: string, recordId: string) {
try {
await isRehydrated()
const result = store.getState().databases[dbName][tableName][recordId]
deep(result)
return 'DONE!'
} catch (e) {
return e
}
}
readRecord(process.argv[2], process.argv[3], process.argv[4]).then(
m => {
log(m)
process.exit()
},
e => {
red(e)
process.exit()
}
)
Is there a simple way to rewrite the above script in Purescript using Purescript's FFI to call the Javascript imports and the do syntax to handle the async procedures?
This answer is a work in progress.
Main.js
"use strict";
exports.store = require('../../../build_server/server/store/index').store
exports.red = require('../../../build_server/src/io/console').red
exports.deep = require('../../../build_server/src/io/console').deep
exports.isRehydrated = require('../../../build_server/scripts/isRehydrated').isRehydrated
exports.path = require('ramda').path
exports.argv = process.argv
exports.exit = process.exit
Main.purs
module Main where
import Prelude
import Control.Promise (toAff, Promise)
import Data.Array (slice)
import Effect (Effect)
import Effect.Aff (Aff, launchAff_)
import Effect.Class (liftEffect)
import Effect.Console (log)
import Foreign (Foreign)
foreign import isRehydrated :: Unit -> Promise Unit
foreign import red :: ∀ a. a -> Effect Unit
foreign import deep :: ∀ a. a -> Effect Unit
foreign import store :: { getState :: Unit -> { databases :: Foreign } }
foreign import path :: Array String -> Foreign -> Foreign
foreign import argv :: Array String
foreign import exit :: Unit -> Effect Unit
recordPath :: Array String
recordPath = slice 2 5 argv
affLog :: String -> Aff Unit
affLog msg = liftEffect $ log msg
affDeep :: ∀ a. a -> Aff Unit
affDeep m = liftEffect $ deep m
affExit :: Unit -> Aff Unit
affExit unit = liftEffect $ exit unit
isRehydratedAff :: Unit -> Aff Unit
isRehydratedAff unit = toAff (isRehydrated unit)
main :: Effect Unit
main = do
log "BEGIN EFF"
launchAff_ do
affLog "BEGIN AFF"
isRehydratedAff unit
affLog "HYDRATED"
affDeep $ path recordPath (store.getState unit).databases
affLog "END AFF"
affExit unit
main.js
require('./src/pursOut/Main/index').main()
At the terminal:
node main.js
I am interested in using more efficient pointers for a project implementing an imperative language in Haskell. There is already a library for that: Struct. There is a blog post on it and brief documentation.
The problem is there is only a quite sophisticated example of linkcut trees. For someone like me who doesn't use Haskell on a daily basis, it is quite exhausting to battle little documented code, template haskell, etc.
I would need a simpler example to get started, along the lines of expressing either of those two data types:
import Data.IORef
data DLL a = DLL a (Maybe (IORef (DLL a))) (Maybe (IORef (DLL a)))
data DLLINT = DLLINT Int (Maybe (IORef DLLINT)) (Maybe (IORef DLLINT))
This should be just a few simple lines for someone who is fluent in Haskell/GHC.
How do I express one of the data types above with the Struct library?
I managed to get your DLL type working with Structs as follows:
{-# LANGUAGE TemplateHaskell, RoleAnnotations #-}
module DubLiList where
import Control.Monad.Primitive
import Data.Struct.TH
import Data.Struct
import Data.Struct.Internal
makeStruct [d|
data DLL a s = DLL
{ prev :: !(DLL a s)
, value :: a
, next :: !(DLL a s)
}
|]
new :: (PrimMonad m) => a -> m (DLL a (PrimState m))
new x = st $ newDLL Nil x Nil
insert :: (PrimMonad m) => a -> DLL a (PrimState m) -> m (DLL a (PrimState m))
insert x this = st $ do
prev' <- get prev this
new <- newDLL prev' x this
set prev this new
set next prev' new
return new
delete :: (PrimMonad m) => DLL a (PrimState m) -> m ()
delete this = st $ do
prev' <- get prev this
next' <- get next this
set next prev' next'
set prev next' prev'
toList :: (PrimMonad m) => DLL a (PrimState m) -> m [a]
toList this = st $ do
if isNil this then return [] else do
x <- getField value this
that <- get next this
(x:) <$> toList that
Here's an example of using it:
main :: IO ()
main = do
dll <- new "foo" -- [foo]
dll' <- insert "bar" dll -- [bar, foo]
insert "baz" dll -- [bar, baz, foo]
xs <- toList dll'
print xs
I want to be able to write
x :: Eff (reader :: Reader Int, maybe :: Maybe) Int
x = do
config <- ask -- configuration from (Reader Int) monad
just config -- using (Maybe) Monad
runX :: Int
runX = runPure (runMaybe doIfNothing (runReader 6 x)) -- outputs: 6
using the Eff Monad
Is this possible to do using Eff?
If not how can we make it work not using Eff?
You can use the MaybeT and ReaderT monad transformers on top of Eff, but you cannot match the two in the way you wrote above:
import Prelude
import Data.Maybe
import Control.Monad.Eff
import Control.Monad.Eff.Class
import Control.Monad.Eff.Console
import Control.Monad.Maybe.Trans
import Control.Monad.Reader.Trans
x :: ReaderT Int (MaybeT (Eff (console :: CONSOLE))) Int
x = do
liftEff (log "Asking...")
config <- ask
pure config
main :: Eff (console :: CONSOLE) (Maybe Int)
main = runMaybeT (runReaderT x 6)
I am writing bindings from History.js into PureScript and still struggling to understand the Eff monad, what a row of effects are and why they are valuable. Right now I have the following written with EasyFFI
type Title = String
type Url = String
type State = forall a. {title :: Title, url :: Url | a}
type Data = forall a. { | a}
type StateUpdater = Data -> Title -> Url -> Unit
-- this function is a work around for 'data' as a reserved word.
foreign import getData
"function getData(state){ return state['data']; }"
:: forall a b. { | a} -> b
unwrapState :: StateUpdater -> State -> Unit
unwrapState f s = f (getData s) s.title s.url
replaceState' :: StateUpdater
replaceState' = unsafeForeignProcedure ["data","title","url"] "History.replaceState(data,title,url)"
replaceState :: State -> Unit
replaceState = unwrapState replaceState'
foreign import data BeforeEach :: !
beforeEach :: forall e a. Eff e a -> Eff (beforeEach :: BeforeEach | e) Unit
beforeEach = unsafeForeignProcedure ["fn",""] "window.beforeEach(fn);"
Later in the code I have the following:
beforeEach $ do
replaceState {title = "wowzers!", url = "/foos"}
and get the following error
Cannot unify Prelude.Unit with Control.Monad.Eff.Eff u2518 u2517.
I've tried manipulating the type signatures in various ways to try and make it all line up, but I don't really understand what is going wrong. So its just guessing at this point.
My modified version of your code is at the end of this post, but I had to make a few modifications in order to make it compile:
I assume the intention was for your StateUpdater to have an effect on the browser history, so I changed its type to use the Eff monad with a new History effect type. This was the main problem, since your last line used replaceState whose result type is not in the Eff monad. This resulted in the type error you saw.
I moved some of the universally quantified type variables in your type synonyms into function types. I also removed your Data type synonym and moved the data content into a new data field in the State type.
This is important, because your previous Data type had no inhabitants. There is a common misconception (for reasons I do not understand) that forall a. { | a} is a type of records "where I don't care about the fields". That is incorrect - this type represents the type of records which contains all fields which could possibly exist, and such a type is clearly uninhabited. There is an important difference between forall a. {| a} -> r and (forall a. {| a}) -> r from the point of view of the caller.
In answer to your original question: "what is a row of effects, and why are they useful?" - rows were originally added to PureScript to deal with polymorphism on record types without having to resort to subtyping. Rows allow us to give polymorphic types to functions which use records, in such a way that we can capture "the rest of the record" as a concept in the type system.
Rows also turned out to be a useful concept when dealing with effects. Just like we don't care what the rest of a record is, we usually don't care what the rest of a set of effects looks like, so long as all effects get propagated correctly in the type system.
To give an example, there are two effects involved in my modified code: History, and your BeforeEach. The actions beforeEach and replaceState each only use one of these effects, but their return types are polymorphic. This allows the combination of the two functions in main to have both effects, and type correctly. main has type forall eff. Eff (history :: History, beforeEach :: BeforeEach | eff) {} which is the most general type, inferred by the type checker.
In short, rows in the effect system provide a neat way to handle the interleaving of various "native" effects, so that the developer does not have to worry about things like the order of effects or lifting computations à la mtl.
module Main where
import EasyFFI
import Control.Monad.Eff
type Title = String
type Url = String
type State d = { title :: Title, url :: Url, "data" :: { | d } }
type StateUpdater d = forall eff. { | d } -> Title -> Url -> Eff (history :: History | eff) {}
foreign import data History :: !
unwrapState :: forall eff d. StateUpdater d -> State d -> Eff (history :: History | eff) {}
unwrapState f s = f s."data" s.title s.url
replaceState' :: forall d. StateUpdater d
replaceState' = unsafeForeignProcedure ["d","title","url"] "History.replaceState(d,title,url)"
replaceState :: forall eff d. State d -> Eff (history :: History | eff) {}
replaceState = unwrapState replaceState'
foreign import data BeforeEach :: !
beforeEach :: forall e a. Eff e a -> Eff (beforeEach :: BeforeEach | e) {}
beforeEach = unsafeForeignProcedure ["fn",""] "window.beforeEach(fn);"
main = beforeEach $ do
replaceState { title: "wowzers!", url: "/foos", "data": {} }