Hatena::Grouphaskell

suztomoの日記

2012-02-11

Ambiguous module name

23:37

別にddump-splicesに限ったわけではないですが。

ghc -ddump-splices Model.hs
~/Documents/OsojiPhoto/OsojiPhoto $ ghc -ddump-splices Model.hs
GooglePlusOAuth.hs:42:8:
    Ambiguous module name `Data.Aeson.Types':
      it was found in multiple packages:
      aeson-0.5.0.0 aeson-native-0.3.3.2

こんなときは

ghc -hide-package aeson-native -ddump-splices Model.hs

参考haskell - Specifying package name for module-related commands in ghci - Stack Overflow

Yesodで新しいHandlerを加えるとき

20:22

たとえばProfileRを加えるときのメモ

  • Handler/ProfileにProfileモジュールを書いてgetProfileRを定義
  • Application.hsにimport Handler.Profile
  • config/routesURLのマッピングを/profile ProfileR GETとかかく
  • .cabalのother-modulesにHandler.Profileを追加

2012-02-08

型をあわせると動く

23:10

そういう不思議な言語です。

httpLbsは2XXなステータスコードじゃないとエラーになるので、それをControl.Exception.Liftedのcatchで拾ってやるのがこつです。

帰ってきたJSONはData.Aesonで処理してあげます。

http://d.hatena.ne.jp/melpon/20111026/1319602571

    getAccessToken :: String -> IO (Maybe Text)
    getAccessToken code = do
      let payload = [("code", C8.pack code), ("client_id", C8.pack key),
                     ("client_secret", C8.pack sec),
                    ("redirect_uri", "http://localhost:3000/auth/page/GooglePlus"),
                    ("grant_type", "authorization_code")]
      parsedUrl <- parseUrl accUrl
      let req = urlEncodedBody payload $ parsedUrl
          errHandler :: ResourceIO m => HttpException
                     -> ResourceT m (Response LBS.ByteString)
          errHandler (StatusCodeException status hdrs) = return $ Response status hdrs LBS.empty
      (status, content) <- withManager $ \manager -> do
                                 Response status _ bsrc <- (httpLbs req manager) `L.catch` errHandler
                                 return (status, bsrc)
      putStrLn $ "Got status: " ++ (show status)
      case status of
        (Status 200 _) -> do
                    let r = AP.eitherResult $ AP.parse json content
                    case r of
                      Left msg -> do
                             putStrLn $ "Json error" ++ msg
                             return Nothing
                      Right d -> do
                             putStrLn "json ok"
                             let Object obj = d
                                 t = do
                                   String txt <- M.lookup "access_token" obj
                                   return txt
                             return t
        _ -> do
          putStrLn "invalid status"
          return Nothing

Haskellの難しいところはいろいろなライブラリが依存関係がいっぱいあるということな気がします。

2012-02-07

初Conduit

00:30

HTTP Postリクエストをしないといけなかったので、Network.HTTP.Conduitを使ってみた。といってもぜんぜんSourceとかSinkとか出てこないけれども。一部抜粋。


    getAccessToken :: String -> IO (Maybe Text)
    getAccessToken code = do
      let payload = [("code", C8.pack code), ("client_id", C8.pack key),
                     ("client_secret", C8.pack sec),
                    ("redirect_uri", "http://localhost:3000/auth/page/GooglePlus"),
                    ("grant_type", "authorization_code")]
      parsedUrl <- parseUrl accUrl
      let req = urlEncodedBody payload $ parsedUrl
      (statusCode, content) <- withManager $ \manager -> do
                                 Response status _ bsrc <- httpLbs req manager
                                 return (status, bsrc)
      putStrLn $ "Got status: " ++ (show statusCode)

Ugoita

Got status: Status {statusCode = 200, statusMessage = "OK"}

StringをByteStringに変換するのはData.ByteString.Char8を使うといいぽい。import qualified Data.ByteString.Char8 as C8。仲間にData.ByteString.UTF-8があるということはきっとユニコードはそっちをつかったほうがいいということだろう。

2012-02-06

because type variable XXX would escape its scope

23:57

because type variable `s' would escape its scope - suztomoの日記 - haskellがとりあえず解けた

Type declarationをしたら動いた。

    login :: forall s m. (Route Auth -> Route m) -> GWidget s m ()
    login tm = do
        render <- lift getUrlRender
        let oaUrl = render $ tm $ oauthUrl name
        addHtml $
          [shamlet| <a href=#{oaUrl}>Login with #{name} |]

参考にしたページ。

Haskell - Haskell-Cafe - Enabling GADTs breaks Rank2Types code compilation - Why?

forallを学ぶ

22:34

Rank2 Type

第20回 更新を高速化するためのSTモナド - 本物のプログラマはHaskellを使う:ITpro

7.8.?Other type system extensions

{-# LANGUAGE Rank2Types #-}
applyTuple :: (forall a. a -> a) -> (Bool, String)
applyTuple f = (f True, f "hidamari")

applyTuple2 :: forall a. (a -> a) -> (Bool, String)
applyTuple2 f = (f True, f "hidamari")

一つ目はfに(Bool -> Bool)がきてもいいし、(String -> String)がきてもいいということ。二つ目は(f True)の時点でaの型が(Bool -> Bool)に固定され、(f "hidamari")の片付け(unification)に失敗する。