title: How to use MultiPiece
body: <p>I'm completely new to Yesod (and not very experienced in haskell) and I'm trying to build my first handler. I scraffolded my app using default parameters (I'm using Yesod 0.9.4.1 version and choose postgresql in scraffolding) and now I'm trying to retrieve some data from a table using selectList. I defined a new table (let's call it Foo) in models config file:</p>
  
  <pre><code>    Foo
          xStart Int
          yStart Int
  </code></pre>
  
  <p>and want to pass a list of FooId's and some other Foo attributes so I defined a route: </p>
  
  <p><code>/foos/#Int/#Int/*FooId FoosReturnR GET</code></p>
  
  <p>and a handler:</p>
  
  <pre><code>    module Handler.FoosReturn where
  
      import Import
  
      selectWindowSize :: Int 
      selectWindowSize = 10000
  
      getFoosReturnR :: Int -&gt; Int -&gt; [FooId] -&gt; Handler RepPlain
      getFoosReturnR x y withoutIds = do
          foos &lt;- runDB $ selectList [FooId /&lt;-. withoutIds, 
                 FooXStart &lt;. x + selectWindowSize,
                 FooXStart &gt;=. x - selectWindowSize, 
                 FooYStart &lt;. y + selectWindowSize,
                 FooYStart &gt;=. y - selectWindowSize] [] 
          return $ RepPlain $ toContent $ show foos
  </code></pre>
  
  <p>I imported the handler in Application.hs and added it to cabal file and now when I'm trying to run it I receive an error saying that FooId is not an instance of MultiPiece - but when I try to make it an instance there is an error saying that FooId is a type synonym and cannot be  an instance of MultiPiece - how to resolve this problem?</p>
  
  <hr>
  
  <p>EDIT:
  Daniel: well, actually I don't know what exactly is FooId - it's a part of Yesod's magic which I don't fully understand so far - it's generated automatically from the table definition - but it's a some kind of a number.</p>
  
  <p>Because I don't know how to use MultiPiece I switched to simpler solution and modified:</p>
  
  <p>route: <code>/foos/#Int/#Int/#String FoosReturnR GET</code></p>
  
  <p>handler: [added also some logging]</p>
  
  <pre><code>    module Handler.FoosReturn where
  
      import Import
      import Data.List.Split
      import qualified Data.Text.Lazy as TL
  
      selectWindowSize :: Int 
      selectWindowSize = 10000
  
      getFoosReturnR :: Int -&gt; Int -&gt; String -&gt; Handler RepPlain
      getFoosReturnR x y withoutIds = do
          app &lt;- getYesod
          liftIO $ logLazyText (getLogger app) ("getFoosReturnR('" `TL.append` (TL.pack $ (show x) ++ "', '" ++ (show y) ++ "', '" ++ withoutIds ++ "') "))
          foos &lt;- runDB $ selectList [FooId /&lt;-. (map (\a -&gt; read a :: FooId) $ splitOn "," withoutIds), 
                 FooXStart &lt;. x + selectWindowSize,
                 FooXStart &gt;=. x - selectWindowSize, 
                 FooYStart &lt;. y + selectWindowSize,
                 FooYStart &gt;=. y - selectWindowSize] [] 
          return $ RepPlain $ toContent $ show foos
  </code></pre>
  
  <p>and now it is compiling but when I browse to: <a href="http://localhost:3000/sectors/1/1/1,2" rel="nofollow">http://localhost:3000/sectors/1/1/1,2</a> I get a page containing only:
              Internal Server Error
              Prelude.read: no parse</p>
  
  <p>Well, I don't fully understand what is FooId here - how to create such a list of FooId's from list of strings containing numbers?</p>
  
  <p>And of course a solution of how to make the FooId an instance of MultiPiece is most wanted.</p>
  
  <hr>
  
  <p>EDIT: </p>
  
  <p>Daniel and svachalek, thanks for your posts - I tried your (Daniel's) solution but then I was receiving errors saying that [FooId] is expected (as in the handler function declaration) but FooId type was given and this lead me to the following solution:</p>
  
  <pre><code>    data FooIds = FooIds [FooId] deriving (Show, Read, Eq)
  
      instance MultiPiece FooIds where
          toMultiPiece (FooIds fooList) = map (Data.Text.pack . show) fooList
          fromMultiPiece texts = 
              if length (filter isNothing listOfMaybeFooId) &gt; 0
                  then Nothing
                  else Just $ FooIds $ map fromJust listOfMaybeFooId
              where 
                  listOfMaybeFooId = map constructMaybeFooId texts
                  constructMaybeFooId :: Text -&gt; Maybe FooId
                  constructMaybeFooId x = case reads (Data.Text.unpack x) :: [(FooId,String)] of
                          [(foo,_)] -&gt; Just foo
                          _         -&gt; Nothing
  </code></pre>
  
  <p>of course I changed the route to: <code>/foos/#Int/#Int/*FooIds FoosReturnR GET</code></p>
  
  <p>and the handler to: </p>
  
  <pre><code>    getFoosReturnR :: Int -&gt; Int -&gt; FooIds -&gt; Handler RepPlain
      getFoosReturnR coordX coordY (FooIds withoutIds) = do
  </code></pre>
  
  <p>and now I don't get any errors during compilation nor runtime, and the only not satisfying thing is that I always receive Not Found as a result, even if I supply parameters that should give me some results - so now I have to figure out how to determine what SQL was exactly sent to the database</p>
  
  <hr>
  
  <p>EDIT:</p>
  
  <p>Now I see that the "Not Found" is connected to the problem and that the above edit is not a solution - when I browse to localhost:3000/foos/4930000/3360000 then I get the results (but then the FooIds is empty) - but when I add something like: localhost:3000/sectors/4930000/3360000/1 then I always get "Not Found" - so it's still not working..</p>