MicrosoftTranslator 0.1.0.0 → 0.1.0.1
raw patch · 2 files changed
+46/−19 lines, 2 filesPVP: major bump suggested
API removals or changes: PVP suggests a major version bump
API changes (from Hackage documentation)
- Language.Bing: instance GHC.Base.Applicative Language.Bing.BingMonad
- Language.Bing: instance GHC.Base.Functor Language.Bing.BingMonad
- Language.Bing: instance GHC.Base.Monad Language.Bing.BingMonad
+ Language.Bing: data BingContext
+ Language.Bing: execBing :: MonadIO m => BingContext -> BingMonad m a -> m (Either BingError (a, BingContext))
+ Language.Bing: getAccessTokenEither :: ClientId -> ClientSecret -> IO (Either BingError BingContext)
+ Language.Bing: getBingCtx :: Monad m => BingMonad m BingContext
+ Language.Bing: instance (GHC.Base.Monad m, Control.Monad.IO.Class.MonadIO m) => GHC.Base.Applicative (Language.Bing.BingMonad m)
+ Language.Bing: instance (GHC.Base.Monad m, Control.Monad.IO.Class.MonadIO m) => GHC.Base.Functor (Language.Bing.BingMonad m)
+ Language.Bing: instance (GHC.Base.Monad m, Control.Monad.IO.Class.MonadIO m) => GHC.Base.Monad (Language.Bing.BingMonad m)
+ Language.Bing: instance Control.Monad.IO.Class.MonadIO m => Control.Monad.IO.Class.MonadIO (Language.Bing.BingMonad m)
+ Language.Bing: instance Control.Monad.Trans.Class.MonadTrans Language.Bing.BingMonad
+ Language.Bing: runExceptT :: ExceptT e m a -> m (Either e a)
- Language.Bing: checkToken :: BingContext -> ExceptT BingError IO BingContext
+ Language.Bing: checkToken :: MonadIO m => BingContext -> ExceptT BingError m BingContext
- Language.Bing: evalBing :: ClientId -> ClientSecret -> BingMonad a -> IO (Either BingError a)
+ Language.Bing: evalBing :: MonadIO m => ClientId -> ClientSecret -> BingMonad m a -> m (Either BingError a)
- Language.Bing: getAccessToken :: ByteString -> ByteString -> ExceptT BingError IO BingContext
+ Language.Bing: getAccessToken :: MonadIO m => ByteString -> ByteString -> ExceptT BingError m BingContext
- Language.Bing: runBing :: BingMonad a -> BingContext -> ExceptT BingError IO a
+ Language.Bing: runBing :: BingMonad m a -> BingContext -> ExceptT BingError m a
- Language.Bing: translateM :: Text -> BingLanguage -> BingLanguage -> BingMonad Text
+ Language.Bing: translateM :: MonadIO m => Text -> BingLanguage -> BingLanguage -> BingMonad m Text
Files
- MicrosoftTranslator.cabal +8/−7
- src/Language/Bing.hs +38/−12
MicrosoftTranslator.cabal view
@@ -2,20 +2,21 @@ -- documentation, see http://haskell.org/cabal/users-guide/ name: MicrosoftTranslator-version: 0.1.0.0+version: 0.1.0.1 synopsis: Interface for Microsoft Translator description:- A simple library to use Microsoft Translator- (<https://www.microsoft.com/en-us/translator/default.aspx>) in Haskell.+ A simple library to use <https://www.microsoft.com/en-us/translator/default.aspx Microsoft Translator> in Haskell. It provides an easy to use interface to the free translation service from Microsoft so one can easily add language translation to a Haskell program as long as there is internet connection available.- + . The easiest way to use the program is via the toplevel translate function:+ . > translate :: ClientId -> ClientSecret -> Text -> BingLanguage -> BingLanguage -> IO (Either BingError Text)-- To use this library one must have an account for Microsoft Translator in the- Azure Data Market. More information about this package available at: (<https://github.com/netogallo/Microsoft-Translator-Haskell>).+ .+ To use this library one must have an account for Microsoft Translator in the+ Azure Data Market. More information about this package available + <https://github.com/netogallo/Microsoft-Translator-Haskell here>. license: BSD3 license-file: LICENSE
src/Language/Bing.hs view
@@ -1,13 +1,18 @@ {-# Language RecordWildCards, OverloadedStrings, DeriveDataTypeable #-} module Language.Bing( BingLanguage(..),+ BingContext, BingError(..), ClientId, ClientSecret, checkToken, evalBing,+ execBing, getAccessToken,+ getAccessTokenEither,+ getBingCtx, runBing,+ runExceptT, translate, translateM) where @@ -41,6 +46,8 @@ import qualified Data.Text.Encoding as TE import qualified Data.Text.IO as TIO import System.IO.Unsafe (unsafePerformIO)+import Control.Monad.Trans.Class+import Control.Monad.IO.Class type ClientId = ByteString @@ -74,11 +81,11 @@ inception :: DateTime, clientId :: ByteString, clientSecret :: ByteString- } deriving Show+ } deriving (Show,Typeable) -newtype BingMonad a = BM {runBing :: BingContext -> ExceptT BingError IO a}+newtype BingMonad m a = BM {runBing :: BingContext -> ExceptT BingError m a} -instance Monad BingMonad where+instance (Monad m, MonadIO m) => Monad (BingMonad m) where m >>= f = BM (\ctx' -> do ctx <- checkToken ctx' res <- runBing m ctx@@ -86,18 +93,24 @@ return a = BM $ \ctx -> return a -instance Functor BingMonad where+instance (Monad m, MonadIO m) => Functor (BingMonad m) where fmap f bm = do v <- bm return $ f v -instance Applicative BingMonad where+instance (Monad m, MonadIO m) => Applicative (BingMonad m) where pure a = return a a <*> b = do a' <- a b' <- b return (a' b') +instance MonadTrans BingMonad where+ lift m = BM $ \ctx -> lift m++instance MonadIO m => MonadIO (BingMonad m) where+ liftIO io = BM $ \ctx -> liftIO io+ instance FromJSON AccessToken where parseJSON (Object v) = build <$> v .: "token_type" <*>@@ -134,9 +147,9 @@ ("to" N.:= (toSym to :: ByteString)) ] -bingAction :: IO (N.Response BL.ByteString) -> ExceptT BingError IO (N.Response BL.ByteString)+bingAction :: MonadIO m => IO (N.Response BL.ByteString) -> ExceptT BingError m (N.Response BL.ByteString) bingAction action = do- res <- lift $ (E.try action :: IO (Either HttpException (N.Response BL.ByteString)))+ res <- lift $ (liftIO $ (E.try action :: IO (Either HttpException (N.Response BL.ByteString)))) case res of Right res -> return res Left ex -> throwE $ BingError $ pack $ show ex@@ -151,7 +164,7 @@ -- | Request a new access token from Azure using the specified client -- id and client secret-getAccessToken :: ByteString -> ByteString -> ExceptT BingError IO BingContext+getAccessToken :: MonadIO m => ByteString -> ByteString -> ExceptT BingError m BingContext getAccessToken clientId clientSecret = do req <- post tokenAuthPage [ "client_id" N.:= clientId,@@ -159,7 +172,7 @@ scopeArg, grantType ]- r <- N.asJSON req+ r <- liftIO $ N.asJSON req let t = r ^. N.responseBody t' <- liftIO $ getCurrentTime return $ BCTX{@@ -171,7 +184,7 @@ -- | Check if the access token of the running BingAction is still -- valid. If the token has expired, renews the token automatically-checkToken :: BingContext -> ExceptT BingError IO BingContext+checkToken :: MonadIO m => BingContext -> ExceptT BingError m BingContext checkToken ctx@BCTX{..} = do t <- liftIO $ getCurrentTime if diffSeconds t inception > expires accessToken - 100 then do@@ -184,7 +197,7 @@ withContext = BM -- | Action that translates text inside a BingMonad context.-translateM :: Text -> BingLanguage -> BingLanguage -> BingMonad Text+translateM :: MonadIO m => Text -> BingLanguage -> BingLanguage -> BingMonad m Text translateM text from to = do let opts = N.defaults & N.param "from" .~ [toSym from :: Text] & N.param "to" .~ [toSym to]@@ -201,10 +214,23 @@ -- | Helper function that evaluates a BingMonad action. It simply -- requests and access token and uses the token for evaluation.-evalBing :: ClientId -> ClientSecret -> BingMonad a -> IO (Either BingError a)+evalBing :: MonadIO m => ClientId -> ClientSecret -> BingMonad m a -> m (Either BingError a) evalBing clientId clientSecret action = runExceptT $ do t <- getAccessToken clientId clientSecret runBing action t++getBingCtx :: Monad m => BingMonad m BingContext+getBingCtx = BM {runBing = \ctx -> return ctx}++execBing :: MonadIO m => BingContext -> BingMonad m a -> m (Either BingError (a,BingContext))+execBing ctx action = runExceptT $ do+ flip runBing ctx $ do+ res <- action+ ctx <- getBingCtx+ return (res,ctx)++getAccessTokenEither :: ClientId -> ClientSecret -> IO (Either BingError BingContext)+getAccessTokenEither clientId clientSecret = runExceptT $ getAccessToken clientId clientSecret -- | Toplevel wrapper that translates a text. It is only recommended if translation -- is invoked less often than every 10 minutes since it always