@Izawa has joined the channel
data EList e a = End e | ECons a (EList e a)
(List a, e) の同型ということですか?Data.List.NonEmpty ではdata ForeignPtr a = ForeignPtr Addr# ForeignPtrContents
data Finalizers = NoFinalizers | CFinalizers (Weak# ()) | HaskellFinalizers [IO ()] data ForeignPtrContents = PlainForeignPtr !(IORef Finalizers) | MallocPtr (MutableByteArray# RealWorld) !(IORef Finalizers) | PlainPtr (MutableByteArray# RealWorld) data ForeignPtr a = ForeignPtr Addr# ForeignPtrContents
IORef Finalizers への参照を保持している理由,というか,この Finalizer という名前の由来がよくわからないんですよね……….GCされるときにただ捨てられるものを指して Finalizer とはどういうことなのか.ForeignPtrContents specially” とか書いているのを見たことないので,ふっつーに扱われるんだろうな,と思っている,と言うのが正しい.mkWeak# を使っているのがポイントのようですね https://gitlab.haskell.org/ghc/ghc/-/blob/a1f34d37b47826e86343e368a5c00f1a4b1f2bce/libraries/base/GHC/ForeignPtr.hs#L586IORef に入っている IO () くらいのものをfinalizerと呼ぶのか,とずっと疑問だったのですが,あれユーザランドで勝手に弄る前提のものではなかったのですね! まずそこにびっくりしていました.exportされてるから,てっきり atomicModifyIORef あたりでユーザが勝手に弄って良いものかと・・・.mkWeak あたりやっと読んできました。 Weak ってFinalizerをつけて作れるんですね。class MonadIO m => MyClass m a | a -> m where foo :: a -> String bar :: a -> m ()
instance HasLogFunc e => MyClass (RIO e) MyData
MyClass の関数従属消せばいいのではないでしょうか?foo に m が現れないので一意に定まらなくなってしまうようなMyClass の従属性と foo の定義がおかしいので見直しが必要な気がしますねlass MonadIO io => Bot io b | b -> io where name :: b -> String reply :: b -> String -> io (Maybe String) instance HasLogFunc env => Bot (RIO env) MarkovChain instance HasLogFunc env => Bot (RIO env) Shiritori
{-# LANGUAGE TypeFamilies #-}
import RIO
import Data.Kind
class Bot b where
type Dep b env :: Constraint
name :: b -> String
reply :: Dep b env => b -> String -> RIO env (Maybe String)
data MarkovChain
instance Bot MarkovChain where
type Dep MarkovChain a = HasLogFunc a
data Shiritori
instance Bot Shiritori where
type Dep Shiritori a = HasLogFunc astreamUpload を使いたいのですが、-- | 自前のYesod環境下を前提としてAwsオペレーションを実行する
runYesodAws :: Yesod App => AWS.AWS a -> HandlerFor App a
runYesodAws x = do
site@App{appLogger, appAwsEnv} <- getYesod
-- ログ定義にAppの定義が必要なためApp自身に予め入れることは出来ない
let awsLogger :: AWS.Logger
awsLogger level builder
= messageLoggerSource site appLogger defaultLoc "amazonka" (toYesodLogLevel level) (toLogStr builder)
runResourceT $ AWS.runAWS (appAwsEnv & AWS.envLogger .~ awsLogger) $ x
-- | amazonkaのログレベルをYesodのログレベルに変換する
toYesodLogLevel :: AWS.LogLevel -> LogLevel
toYesodLogLevel = LevelInfo
toYesodLogLevel AWS.Error = LevelError
toYesodLogLevel AWS.Debug = LevelDebug
toYesodLogLevel AWS.Trace = LevelOther "Trace" MonadFail のインスタンスを定義していないので動かせなくて困っています。fail = error となるだけで良いのですが、liftIO してIOで実行してHandlerForに移せば良いのではないか?なども考えてみたのですが、import Control.Monad.Fail import Control.Monad.Trans.AWS (AWST') instance MonadFail (AWST' AWS.Env (ResourceT IO)) where fail = error
MonadFail のインスタンスが無くて困ってるのはAWST' Env (ResourceT IO) の方でしたねstreamUpload が Either を返すにもかかわらず MonadFailを要求している点であると思うので、そこはissueとして報告したいですね.... Left に SomeExcpetion があるんだから、そいつが担うこともできるでしょうに。 :cold_sweat: