From: fr33domlover <fr33domlo...@riseup.net>

This is a new version of the patch, it uses runStripe in appStripe. It
avoids the StripeClient mess but still has a type error due to
StripeRunner being having the 'forall io' thing. The errors can be fixed
using type annotations probably, but using those in every single place
'snowstripe' is used would be ridiculous.

Honestly idk much about Rank N types. I read about it and did some web
search. And I still don't understand how to properly fix this type error
thing. I think the error is simpler now but idk how to *elegantly* fix it.
---
 crowdmatch/crowdmatch.cabal        |  3 ++-
 crowdmatch/src/Crowdmatch.hs       |  7 +++++++
 website/src/AppDataTypes.hs        |  8 ++++----
 website/src/Application.hs         |  7 ++-----
 website/src/Handler/PaymentInfo.hs | 11 ++---------
 website/src/Handler/Util.hs        |  9 +++++----
 6 files changed, 22 insertions(+), 23 deletions(-)

diff --git a/crowdmatch/crowdmatch.cabal b/crowdmatch/crowdmatch.cabal
index d378766..2c602f1 100644
--- a/crowdmatch/crowdmatch.cabal
+++ b/crowdmatch/crowdmatch.cabal
@@ -28,7 +28,8 @@ library
     hs-source-dirs: src
     default-language: Haskell2010
     build-depends:
-        base >=4.8 && <4.9
+          aeson
+        , base >=4.8 && <4.9
         , bytestring >= 0.10.6.0
         , errors
         , lens
diff --git a/crowdmatch/src/Crowdmatch.hs b/crowdmatch/src/Crowdmatch.hs
index fe61387..a857c2a 100644
--- a/crowdmatch/src/Crowdmatch.hs
+++ b/crowdmatch/src/Crowdmatch.hs
@@ -58,10 +58,12 @@ import Control.Error (ExceptT(..), runExceptT, note)
 import Control.Lens ((^.), from, view, Iso', iso)
 import Control.Monad (void)
 import Control.Monad.IO.Class (MonadIO, liftIO)
+import Data.Aeson (FromJSON)
 import Data.Function (on)
 import Data.Int (Int32)
 import Data.Ratio
 import Data.Time (UTCTime, getCurrentTime, utctDay)
+import Data.Typeable (Typeable)
 import Database.Persist
 import Database.Persist.Sql (SqlPersistT)
 import System.IO
@@ -73,6 +75,7 @@ import Web.Stripe.Customer
         , createCustomer
         , deleteCustomer)
 import Web.Stripe.Error (StripeError)
+import Web.Stripe.StripeRequest (StripeRequest, StripeReturn)
 
 import Crowdmatch.Model hiding (Patron(..))
 import qualified Crowdmatch.Model as Model
@@ -87,6 +90,10 @@ import qualified Crowdmatch.Skeleton as Skeleton
 -- | A method that runs 'SqlPersistT' values in your environment.
 type SqlRunner io env = forall a. SqlPersistT io a -> env a
 
+type StripeClient = forall a.
+    (Typeable (StripeReturn a), FromJSON (StripeReturn a)) =>
+    StripeConfig -> StripeRequest a -> IO (Either StripeError (StripeReturn a))
+
 -- | A method that runs 'StripeI' instructions in IO. A default that uses
 -- 'stripe' is provided by 'runStripe'.
 type StripeRunner = forall io.
diff --git a/website/src/AppDataTypes.hs b/website/src/AppDataTypes.hs
index 39ea400..50d2526 100644
--- a/website/src/AppDataTypes.hs
+++ b/website/src/AppDataTypes.hs
@@ -16,6 +16,7 @@ import Yesod.Core.Types (Logger)
 import Yesod.GitRev
 
 import AuthSite
+import Crowdmatch
 import Settings
 
 -- | The God-object available to every Handler. This is the site's
@@ -30,10 +31,9 @@ data App = App
     , appAuth        :: AuthSite
       -- | The function for doing stripe API calls. Swapped out for a mock
       -- thing in tests.
-    , appStripe      :: forall a. (Typeable (StripeReturn a), FromJSON 
(StripeReturn a))
-                     => StripeConfig
-                     -> StripeRequest a
-                     -> IO (Either StripeError (StripeReturn a))
+    , appStripe      :: StripeConfig
+                     -> forall a. StripeI a
+                     -> HandlerT App IO (Either StripeError a)
     }
 
 -- This function generates the route types, and also generates the
diff --git a/website/src/Application.hs b/website/src/Application.hs
index 761d3f8..b6b20db 100644
--- a/website/src/Application.hs
+++ b/website/src/Application.hs
@@ -33,6 +33,7 @@ import Web.Stripe
 import Web.Stripe.Error
 import qualified Yesod.GitRev as G
 
+import Crowdmatch
 import Handler
 import Handler.Dashboard
 import Handler.Discourse
@@ -61,11 +62,7 @@ makeFoundation appSettings = do
         (if appMutableStatic appSettings then staticDevel else static)
         (appStaticDir appSettings)
 
-    let appStripe :: (Typeable (StripeReturn a), FromJSON (StripeReturn a))
-                  => StripeConfig
-                  -> StripeRequest a
-                  -> IO (Either StripeError (StripeReturn a))
-        appStripe = stripe
+    let appStripe = runStripe
 
     let appAuth = AuthSite
     -- We need a log function to create a connection pool. We need a connection
diff --git a/website/src/Handler/PaymentInfo.hs 
b/website/src/Handler/PaymentInfo.hs
index 80c66b9..f17babd 100644
--- a/website/src/Handler/PaymentInfo.hs
+++ b/website/src/Handler/PaymentInfo.hs
@@ -54,20 +54,14 @@ deletePaymentInfoForm :: Form ()
 deletePaymentInfoForm =
     identifyForm delFormId (renderDivsNoLabels deleteFromPost)
 
-stripeConf :: Handler StripeConfig
-stripeConf = fmap
-    (StripeConfig . appStripeSecretKey . appSettings)
-    getYesod
-
 postPaymentInfoR :: Handler Html
 postPaymentInfoR = handleDelete delFormId deletePaymentInfoR $ do
     Entity uid User{..} <- requireAuth
-    conf <- stripeConf
     ((formResult, _), _) <-
         runFormPost (identifyForm modFormId (paymentForm ""))
     case formResult of
         FormSuccess token -> do
-            stripeRes <- runDB $ storePaymentToken (runStripe conf) uid token
+            stripeRes <- runDB $ storePaymentToken snowstripe uid token
             case stripeRes of
                 Left e -> stripeError e
                 Right _ -> do
@@ -79,9 +73,8 @@ postPaymentInfoR = handleDelete delFormId deletePaymentInfoR 
$ do
 
 deletePaymentInfoR :: Handler Html
 deletePaymentInfoR = do
-    conf <- stripeConf
     Entity uid User {..} <- requireAuth
-    stripeDeletionHandler =<< runDB (deletePaymentToken (runStripe conf) uid)
+    stripeDeletionHandler =<< runDB (deletePaymentToken snowstripe uid)
     redirect DashboardR
   where
     stripeDeletionHandler =
diff --git a/website/src/Handler/Util.hs b/website/src/Handler/Util.hs
index ca100f9..11de8aa 100644
--- a/website/src/Handler/Util.hs
+++ b/website/src/Handler/Util.hs
@@ -1,3 +1,5 @@
+{-# LANGUAGE RankNTypes #-}
+
 module Handler.Util
         ( snowdriftTitle
         , snowdriftDashTitle
@@ -25,10 +27,9 @@ snowdriftDashTitle x y = snowdriftTitle $ x `mappend` " — " 
`mappend` y
 
 snowstripe :: StripeI a -> Handler (Either StripeError a)
 snowstripe req = do
-    conf <- fmap
-        (StripeConfig . appStripeSecretKey . appSettings)
-        getYesod
-    liftIO (runStripe conf req)
+    conf <- getsYesod $ StripeConfig . appStripeSecretKey . appSettings
+    runner <- getsYesod appStripe
+    runner conf req
 
 -- | The form element that can be inserted to handle a delete.
 deleteFromPost
-- 
1.9.1

_______________________________________________
Dev mailing list
Dev@lists.snowdrift.coop
https://lists.snowdrift.coop/mailman/listinfo/dev

Reply via email to