How do I preform IO in a Yesod Form? AKA, what is the equivalent of aformM in Yesod 1.2? - yesod

I am trying to learn Yesod 1.2 and I can't figure out how to access IO and information stored in the YesodAuth instance.
For example, I can't figure out how to call getCurrentTime in Yesod 1.2. In Yesod 1.1 you could get the current time inside a form by calling "aformM (liftIO getCurrentTime)"
Similarly, with Yesod 1.2 I can't figure out how to call "requireAuthId".
With Yesod 1.1, you get could these two bits of data with the two lines of code starting with <*> aformM in this snippet:
commentForm :: EntryId -> Form Comment
commentForm entryId = renderDivs $ Comment
<$> pure entryId
<*> aformM (liftIO getCurrentTime)
<*> aformM requireAuthId
<*> areq textField (fieldSettingsLabel MsgCommentName) Nothing
<*> areq textareaField (fieldSettingsLabel MsgCommentText) Nothing
I have currently resorted to querying these in the code that calls "commentForm", but this seems silly as now I have to obtain the time and user's ID multiple times.
commentForm :: UTCTime -> UserId -> EntryId -> Form Comment
commentForm theTime userId entryId = renderDivs $ Comment
<$> pure entryId
<*> pure theTime
<*> pure userId
<*> areq textField (fieldSettingsLabel MsgCommentName) Nothing
<*> areq textareaField (fieldSettingsLabel MsgCommentText) Nothing
Help! I've been over the docs a bunch of times and I just can't wrap my head around it.

Funny, I updated the blog example just a few hours ago to include this right way to do it, together with an explanation of why it's necessary. Short version:
lift (liftIO getCurrentTime)

Related

What is a neat way to load and store a list of images by name in Haskell?

I want to load a list (or any data structure) of images using a bunch of hardcoded names and an existing function loadImage :: String -> IO Image.
In Lua, I would do the following:
imageNames = {"background", "gun", "man"}
images = {}
for i,v in ipairs(imageNames) do
images[v] = loadImage(v..".png")
end
And access them with images.background, images.man etc. How could I go about this in Haskell?
import Data.Map
imageNames :: [String]
imageNames = ["background", "gun", "man"]
images :: [IO (String, Image)]
images = [loadImage(name ++ ".png") >>= return . (,) name | name <- imageNames]
main = do
imgs <- sequence images
let imageMap = fromList imgs
return ()
imageMap is a Map from which you can access a image by its name : imageMap ! "gun"
Basically what Ankur said, I probably wouldn't have an explicit 'images' list and would probably use JuicyPixels to do the loading:
import Data.Map
import Codec.Picture
images :: [String]
images = ["background", "gun", "man"]
main = do
imgs <- mapM loadImage images
let imageMap = fromList (zip images imgs)
return ()
loadImage :: IO DynamicImage
loadImage = either id (error "Bad Image") `fmap` readImage
I'm a little late to the party, but here's another way to do it. It works on a slightly different principle than the other solutions, but the end result is the same.
import Data.Map (insert, empty)
import Data.List (foldl')
import Control.Applicative ((<$>))
import Control.Monad (forM)
imageNames = ["background", "gun", "man"]
images = foldl' (flip id) empty <$> forM imageNames (\name ->
insert name <$> loadImage (name ++ ".png")
)
What images does is that it builds a list of insert operations that are waiting to be performed on a Map. It then uses foldl' to thread a Map through the list of insert operations. As the fold goes along it uses the insert operations to build a larger and larger Map with the desired values. In other words, this does not build an intermediary [(String, Image)] which it then converts to a Map String Int.
The IO is carried all the way from loadImage to the outer function with <$> and sequence, giving the resulting type IO (Map String Image).
I think the other solutions are much easier to read (and probably a lot more efficient as well), so I recommend one of them. I just wanted to throw this out there.

instance Alternative ZipList in Haskell?

ZipList comes with a Functor and an Applicative instance (Control.Applicative) but why not Alternative?
Is there no good instance?
What about the one proposed below?
Is it flawed?
is it useless?
Are there other reasonable possibilities (like Bool can be a monoid in two ways) and therefore neither should be the instance?
I searched for "instance Alternative ZipList" (with the quotes to find code first) and only found the library, some tutorials, lecture notes yet no actual instance.
Matt Fenwick said ZipList A will only be a monoid if A is (see here). Lists are monoids though, regardless of the element type.
This other answer by AndrewC to the same question discusses how an Alternative instance might look like. He says
There are two sensible choices for Zip [1,3,4] <|> Zip [10,20,30,40]:
Zip [1,3,4] because it's first - consistent with Maybe
Zip [10,20,30,40] because it's longest - consistent with Zip [] being discarded
where Zip is basically ZipList.
I think the answer should be Zip [1,3,4,40]. Let's see the instance:
instance Aternative Zip where
empty = Zip []
Zip xs <|> Zip ys = Zip (go xs ys) where
go [] ys = ys
go (x:xs) ys = x : go xs (drop 1 ys)
The only Zip a we can produce without knowing the type argument a is Zip [] :: Zip a, so there is little choice for empty. If the empty list is the neutral element of the monoid, we might be tempted to use list concatenation. However, go is not (++) because of the drop 1. Every time we use one entry of the first argument list, we drop one off the second as well. Thus we have a kind of overlay: The left argument list hides the beginning of the right one (or all of it).
[ 1, 3, 4,40] [10,20,30,40] [ 1, 3, 4] [ 1, 3, 4]
^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^
| | | | | | | | | | | | | |
[ 1, 3, 4] | [10,20,30,40] []| | | [ 1, 3, 4]
[10,20,30,40] [ 1, 3, 4] [ 1, 3, 4] []
One intuition behind ziplists is processes: A finite or infinite stream of results. When zipping, we combine streams, which is reflected by the Applicative instance. When the end of the list is reached, the stream doesn't produce further elements. This is where the Alternative instance comes in handy: we can name a concurrent replacement (alternative, really), taking over as soon as the default process terminates.
For example we could write fmap Just foo <|> pure Nothing to wrap every element of the ziplist foo into a Just and continue with Nothing afterwards. The resulting ziplist is infinite, reverting to a default value after all (real) values have been used up. This could of course be done by hand, by appending an infinite list inside the Zip constructor. Yet the above is more elegant and does not assume knowledge of constructors, leading to higher code reusability.
We don't need any assumption on the element type (like being a monoid itself). At the same time the definition is not trivial (as (<|>) = const would be). It makes use of the list structure by pattern matching on the first argument.
The definition of <|> given above is associative and the empty list really is the empty element. We have
Zip [] <*> xs == fs <*> Zip [] == Zip [] -- 0*x = x*0 = 0
Zip [] <|> xs == xs <|> Zip [] == xs -- 0+x = x+0 = x
(fs <|> gs) <*> xs == fs <*> xs <|> gs <*> xs
fs <*> (xs <|> ys) == fs <*> xs <|> fs <*> ys
so all the laws you could ask for are satisfied (which is not true for list concatenation).
This instance is consistent with the one for Maybe: choice is biased to the left, yet when the left argument is unable to produce a value, the right argument takes over. The functions
zipToMaybe :: Zip a -> Maybe a
zipToMaybe (Zip []) = Nothing
zipToMaybe (Zip (x:_)) = Just x
maybeToZip :: Maybe a -> Zip a
maybeToZip Nothing = Zip []
maybeToZip (Just x) = Zip (repeat x)
are morphisms of alternatives (meaning psi x <|> psi y = psi (x <|> y) and psi x <*> psi y = psi (x <*> y)).
Edit: For the some/many methods I'd guess
some (Zip z) = Zip (map repeat z)
many (Zip z) = Zip (map repeat z ++ repeat [])
Tags / Indeces
Interesting. A not completely unrelated thought: ZipLists can be seen as ordinary lists with elements tagged by their (increasing) position index in the list. Zipping application joins two lists by pairing equally-indexed elements.
Imagine lists with elements tagged by (non-decreasing) Ord values. Zippery application would pair-up equally-tagged elements, throwing away all mismatches (it has its uses); zippery alternative could perform order-preserving left-preferring union on tag values (alternative on regular lists is also kind of a union).
This fully agrees with what you propose for indexed lists (aka ZipLists).
So yes, it makes sense.
Streams
One interpretation of a list of values is non-determinacy, which is consistent with the monad instance for lists, but ZipLists can be interpreted as synchronous streams of values which are combined in sequence.
With this stream interpretation it's you don't think in terms of the whole list, so choosing the longest stream is clearly cheating, and the correct interpretation of failing over from the first ZipList to the second in the definition <|> would be to do so on the fly as the first finishes, as you say in your instance.
Zipping two lists together doesn't do this simply because of the type signature, but it's the correct interpretation of <|>.
Longest Possible List
When you zip two lists together, the result is the minimum of the two lengths. This is because that's the longest possible list that meets the type signature without using ⊥. It's a mistake to think of this as picking the shorter of the two lengths - it's the longest possible.
Similarly <|> should generate the longest possible list, and it should prefer the left list. Clearly it should take the whole of the left list and take up the right list where the left left off to preserve synchronisation/zippiness.
Your instance is OK, but it does something ZipList doesn't by
(a) aiming for the longest list, and
(b) mixing elements between source lists.
Zipping as an operation stops at the length of the shortest list.
That's why I concluded in my answer:
Thus the only sensible Alternative instance is:
instance Alternative Zip where
empty = Zip []
Zip [] <|> x = x
Zip xs <|> _ = Zip xs
This is consistent with the Alternative instances for Maybe and parsers that say you should do a if it doesn't fail and go with b if it does. You can say a shorter list is less successful than a longer one, but I don't think you can say a non-empty list is a complete fail.
empty = Zip [] is chosen because it has to be polymorphic in the element type of the list, and the only such list is []
For balance, I don't think your instance is terrible, I think this is cleaner, but hey ho, roll your own as you need it!
There is in fact a sensible Alternative instance for ZipList. It comes from a paper on free near-semirings (which MonadPlus and Alternative are examples of):
instance Alternative ZipList where
empty = ZipList []
ZipList xs <|> ZipList ys = ZipList $ go xs ys where
go [] bs = bs
go as [] = as
go (a:as) (_:bs) = a:go as bs
This is a more performant version of the original code for it, which was
ZipList xs <|> ZipList ys = ZipList $ xs ++ drop (length xs) ys
My guiding intuition for Alternative comes from parsers which suggest that if one branch of your alternative fails somehow it should be eradicated thus leading to a Longest-style Alternative that probably isn't terrifically useful. This would be unbiased (unlike parsers) but fail on infinite lists.
Then again, all they must do, as you suggest, is form a Monoid. Yours is left biased in a way that ZipList doesn't usually embody, though—you could clearly form the reflected version of your Alternative instance just as easily. As you point out, this is the convention with Maybe as well, but I'm not sure there's any reason for ZipList to follow that convention.
There's no sensible some or many I don't believe, although few Alternatives actually have those—perhaps they'd have been better isolated into a subclass of Alternative.
Frankly, I don't think your suggestion is a bad instance to have, but I don't have any confidence about it being "the" alternative instance implied by having a ZipList. Perhaps it'd be best to see where else this kind of "extension" instance could apply (trees?) and write it as a library.

Haskell: Scan Through a List and Apply A Different Function for Each Element

I need to scan through a document and accumulate the output of different functions for each string in the file. The function run on any given line of the file depends on what is in that line.
I could do this very inefficiently by making a complete pass through the file for every list I wanted to collect. Example pseudo-code:
at :: B.ByteString -> Maybe Atom
at line
| line == ATOM record = do stuff to return Just Atom
| otherwise = Nothing
ot :: B.ByteString -> Maybe Sheet
ot line
| line == SHEET record = do other stuff to return Just Sheet
| otherwise = Nothing
Then, I would map each of these functions over the entire list of lines in the file to get a complete list of Atoms and Sheets:
mapper :: [B.ByteString] -> IO ()
mapper lines = do
let atoms = mapMaybe at lines
let sheets = mapMaybe to lines
-- Do stuff with my atoms and sheets
However, this is inefficient because I am maping through the entire list of strings for every list I am trying to create. Instead, I want to map through the list of line strings only once, identify each line as I am moving through it, and then apply the appropriate function and store these values in different lists.
My C mentality wants to do this (pseudo code):
mapper' :: [B.ByteString] -> IO ()
mapper' lines = do
let atoms = []
let sheets = []
for line in lines:
| line == ATOM record = (atoms = atoms ++ at line)
| line == SHEET record = (sheets = sheets ++ ot line)
-- Now 'atoms' is a complete list of all the ATOM records
-- and 'sheets' is a complete list of all the SHEET records
What is the Haskell way of doing this? I simply can't get my functional-programming mindset to come up with a solution.
First of all, I think that the answers others have supplied will work at least 95% of the time. It's always good practice to code for the problem at hand by using appropriate data types (or tuples in some cases). However, sometimes you really don't know in advance what you're looking for in the list, and in these cases trying to enumerate all possibilities is difficult/time-consuming/error-prone. Or, you're writing multiple variants of the same sort of thing (manually inlining multiple folds into one) and you'd like to capture the abstraction.
Fortunately, there are a few techniques that can help.
The framework solution
(somewhat self-evangelizing)
First, the various "iteratee/enumerator" packages often provide functions to deal with this sort of problem. I'm most familiar with iteratee, which would let you do the following:
import Data.Iteratee as I
import Data.Iteratee.Char
import Data.Maybe
-- first, you'll need some way to process the Atoms/Sheets/etc. you're getting
-- if you want to just return them as a list, you can use the built-in
-- stream2list function
-- next, create stream transformers
-- given at :: B.ByteString -> Maybe Atom
-- create a stream transformer from ByteString lines to Atoms
atIter :: Enumeratee [B.ByteString] [Atom] m a
atIter = I.mapChunks (catMaybes . map at)
otIter :: Enumeratee [B.ByteString] [Sheet] m a
otIter = I.mapChunks (catMaybes . map ot)
-- finally, combine multiple processors into one
-- if you have more than one processor, you can use zip3, zip4, etc.
procFile :: Iteratee [B.ByteString] m ([Atom],[Sheet])
procFile = I.zip (atIter =$ stream2list) (otIter =$ stream2list)
-- and run it on some data
runner :: FilePath -> IO ([Atom],[Sheet])
runner filename = do
resultIter <- enumFile defaultBufSize filename $= enumLinesBS $ procFile
run resultIter
One benefit this gives you is extra composability. You can create transformers as you like, and just combine them with zip. You can even run the consumers in parallel if you like (although only if you're working in the IO monad, and probably not worth it unless the consumers do a lot of work) by changing to this:
import Data.Iteratee.Parallel
parProcFile = I.zip (parI $ atIter =$ stream2list) (parI $ otIter =$ stream2list)
The result of doing so isn't the same as a single for-loop - this will still perform multiple traversals of the data. However, the traversal pattern has changed. This will load a certain amount of data at once (defaultBufSize bytes) and traverse that chunk multiple times, storing partial results as necessary. After a chunk has been entirely consumed, the next chunk is loaded and the old one can be garbage collected.
Hopefully this will demonstrate the difference:
Data.List.zip:
x1 x2 x3 .. x_n
x1 x2 x3 .. x_n
Data.Iteratee.zip:
x1 x2 x3 x4 x_n-1 x_n
x1 x2 x3 x4 x_n-1 x_n
If you're doing enough work that parallelism makes sense this isn't a problem at all. Due to memory locality, the performance is much better than multiple traversals over the entire input as Data.List.zip would make.
The beautiful solution
If a single-traversal solution really does make the most sense, you might be interested in Max Rabkin's Beautiful Folding post, and Conal Elliott's followup work (this too). The essential idea is that you can create data structures to represent folds and zips, and combining these lets you create a new, combined fold/zip function that only needs one traversal. It's maybe a little advanced for a Haskell beginner, but since you're thinking about the problem you may find it interesting or useful. Max's post is probably the best starting point.
I show a solution for two types of line, but it is easily extended to five types of line by using a five-tuple instead of a two-tuple.
import Data.Monoid
eachLine :: B.ByteString -> ([Atom], [Sheet])
eachLine bs | isAnAtom bs = ([ {- calculate an Atom -} ], [])
| isASheet bs = ([], [ {- calculate a Sheet -} ])
| otherwise = error "eachLine"
allLines :: [B.ByteString] -> ([Atom], [Sheet])
allLines bss = mconcat (map eachLine bss)
The magic is done by mconcat from Data.Monoid (included with GHC).
(On a point of style: personally I would define a Line type, a parseLine :: B.ByteString -> Line function and write eachLine bs = case parseLine bs of .... But this is peripheral to your question.)
It is a good idea to introduce a new ADT, e.g. "Summary" instead of tuples.
Then, since you want to accumulate the values of Summary you came make it an istance of Data.Monoid. Then you classify each of your lines with the help of classifier functions (e.g. isAtom, isSheet, etc.) and concatenate them together using Monoid's mconcat function (as suggested by #dave4420).
Here is the code (it uses String instead of ByteString, but it is quite easy to change):
module Classifier where
import Data.List
import Data.Monoid
data Summary = Summary
{ atoms :: [String]
, sheets :: [String]
, digits :: [String]
} deriving (Show)
instance Monoid Summary where
mempty = Summary [] [] []
Summary as1 ss1 ds1 `mappend` Summary as2 ss2 ds2 =
Summary (as1 `mappend` as2)
(ss1 `mappend` ss2)
(ds1 `mappend` ds2)
classify :: [String] -> Summary
classify = mconcat . map classifyLine
classifyLine :: String -> Summary
classifyLine line
| isAtom line = Summary [line] [] [] -- or "mempty { atoms = [line] }"
| isSheet line = Summary [] [line] []
| isDigit line = Summary [] [] [line]
| otherwise = mempty -- or "error" if you need this
isAtom, isSheet, isDigit :: String -> Bool
isAtom = isPrefixOf "atom"
isSheet = isPrefixOf "sheet"
isDigit = isPrefixOf "digits"
input :: [String]
input = ["atom1", "sheet1", "sheet2", "digits1"]
test :: Summary
test = classify input
If you have only 2 alternatives, using Either might be a good idea. In that case combine your functions, map the list, and use lefts and rights to get the results:
import Data.Either
-- first sample function, returning String
f1 x = show $ x `div` 2
-- second sample function, returning Int
f2 x = 3*x+1
-- combined function returning Either String Int
hotpo x = if even x then Left (f1 x) else Right (f2 x)
xs = map hotpo [1..10]
-- [Right 4,Left "1",Right 10,Left "2",Right 16,Left "3",Right 22,Left "4",Right 28,Left "5"]
lefts xs
-- ["1","2","3","4","5"]
rights xs
-- [4,10,16,22,28]

haskell list of tuples, with unique tuples

I come from a Python and Java background so Haskell is quite different for me. I'm trying little activities to learn but I am stuck on this .
I have an ordered list of tuples, [(name, studentNumber)], and I want to filter this list so that each student and each studentNumber appears only once. Since the tuples are ordered, I want to keep the first instance of a name or studentNumber and remove any others that may show up.
I tried doing a list comphrenshion, but I'm not sure how to check if a name or number has already been added to the list.
It sounds as if you'd want (as a first, inefficient approximation) something like this:
import Data.List (nubBy)
import Data.Function (on)
filt = nubBy ((==) `on` snd) . nubBy ((==) `on` fst)
The first call to nubBy will result in a list in which each name appears only once, and that will then be passed to the second, resulting in a list in which each number appears only once.
Just using nub will result in a list in which each (name,number) pair occurs only once; there might still be repetitions of names with different numbers and numbers with different names.
(Of course something custom with an accumulator would be faster.)
You can spy on Data.List sources and write your extended nub function:
type Student = (Name, Number)
type Name = String
type Number = Int
unique :: [Student] -> [Student]
unique = go [] []
where
go unames unumbers (s#(name, number):ss)
| name `elem` unames || number `elem` unumbers = go unames unumbers ss
| otherwise = s : go (name:unames) (number:unumbers) ss
go _ _ [] = []
Should do what you want.
To unique-ify a list there's always the nub function from the prelude, I think that should do exactly what you need!

Adding a Show instance to RWH's RandomState example

I have just typed in the RandomState example from real world haskell. It looks like this:
import System.Random
import Control.Monad.State
type RandomState a = State StdGen a
getRandom :: Random a => RandomState a
getRandom =
get >>= \gen ->
let (val, gen') = random gen in
put gen' >>
return val
getTwoRandoms :: Random a => RandomState (a, a)
getTwoRandoms = liftM2 (,) getRandom getRandom
It works, but the result doesn't get displayed. I get the error message:
No instance for (Show (RandomState (Int, Int)))
arising from a use of `print' at <interactive>:1:0-38
Possible fix:
add an instance declaration for (Show (RandomState (Int, Int)))
In a stmt of a 'do' expression: print it
I am having some trouble adding an instance for Show RandomState. Can anyone show me how this is done?
Thanks.
For the sake of being explicit, as jberryman and the comments on the question imply: Something of type RandomState (a, a) is a function, not a value. To do anything with it, you want to run it with an initial state.
I'm guessing you want something like this:
> fmap (runState getTwoRandoms) getStdGen
((809219598,1361755735),767966517 1872071452)
This is essentially what the runTwoRandoms function a bit further in RWH is doing.
Since RandomState is a synonym for State and there isn't an instance of show defined for State, you won't be able to show it.
You would also not be able to derive show because State is just a wrapper for a function and Haskell has no way to define a show for functions that would be useful:
Prelude> show (+)
<interactive>:1:0:
No instance for (Show (a -> a -> a))
arising from a use of `show' at <interactive>:1:0-7
Possible fix: add an instance declaration for (Show (a -> a -> a))
In the expression: show (+)
In the definition of `it': it = show (+)
EDIT: Forgot to add the other piece: GHCi is giving you that error because it uses show behind the scenes on the expressions you enter... REPL and all that.