Kouji Okamoto
@Kouji Okamoto has joined the channel
xmonad-contrib
) の XMonad.Hooks.DynamicLog.statusBar
を用いて実行した場合と、直接バイナリを叩いた場合(bashから、 /bin/sh -c "与えられた実行可能ファイル"
) の挙動が違う現象に遭遇して困っています。(xmonadからの場合はUTF8文字列が描画できず、直接ならできる)statusBar
は内部では System.Posix.Process.ExecuteFile
を叩いており(/bin/sh -c "与えた実行可能ファイル"
を(execvシステムコールを用いて)実行しています。xmonad-contrib
) の XMonad.Hooks.DynamicLog.statusBar
を用いて実行した場合と、直接バイナリを叩いた場合(bashから、 /bin/sh -c "与えられた実行可能ファイル"
) の挙動が違う現象に遭遇して困っています。(xmonadからの場合はUTF8文字列が描画できず、直接ならできる)statusBar
は内部では System.Posix.Process.ExecuteFile
を叩いており(/bin/sh -c "与えた実行可能ファイル"
を(execvシステムコールを用いて)実行しています。Stream
の質問で,リストに変換する方法を二つほど思いついたんです.ひとつはふつうにやる方法(下のコードの streamToList
),もう一つは,Monadが PrimMonad
であることを前提にして 書き込み可能配列に書いておく方法 (下のコードの streamToList2
)です.Monadic Stream の Monad が PrimMonad
であるとき,これらの方法って一致するのかどうかがわからなくて…どなたか反例を思いつく方っていらっしゃいます?import Control.Monad.Primitive implementationOmitted :: a implementationOmitted = undefined ------------------- Growable Vector API -------------------------------- -- | Extendable boxed vector. data GrowableVector s a = DefinitionOmitted createEmpty' :: ST s (GrowableVector s a) createEmpty' = implementationOmitted length' :: GrowableVector s a -> ST s Int length' = implementationOmitted -- append to a vector. The length of the vector will be incremented by one. append' :: GrowableVector s a -> a -> ST s () append' = implementationOmitted -- write into a vector. The index shall be within the length of the vector; -- otherwise the behavior is undefined. write' :: GrowableVector s a -> Int -> a -> ST s () write' = implementationOmitted appendOrWrite' :: GrowableVector s a -> Int -> a -> ST s () appendOrWrite' v i a | i < 0 = error "Negative index not allowed" | otherwise = do l <- length' v if i < l then write' v i a else append v a -- Safely copies the current snapshot of a vector into a list. freeze' :: GrowableVector s a -> ST s [a] freeze' v = implementationOmitted freezeTill' :: Int -> GrowableVector s a -> ST s [a] freezeTill' i v = fmap (take i) $ freeze' v ---------------- PrimMonad wrappers for Growable Vector -------------- createEmpty :: PrimMonad m => m (GrowableVector (PrimMonad m) a) createEmpty = stToPrim createEmpty' appendOrWrite :: PrimMonad m => GrowableVector (PrimMonad m) a -> Int -> a -> m () appendOrWrite = stToPrim appendOrWrite' freezeTill :: PrimMonad m => Int -> GrowableVector (PrimMonad m) a -> m [a] freezeTill = stToPrim freezeTill' -------------- Stream and its conversion to list --------------- data Stream m a = forall s. Stream (s -> m (Step s a)) s data Step s a = Yield a s | Skip s | Done -- convert a stream to a list. streamToList :: Monad m => Stream m a -> m [a] streamToList (Stream step s0) = go s0 where go s = do r <- step s case r of Yield a t -> (:) a <$> go t Skip t -> go t Done -> return [] -- convert a stream to a list. streamToList2 :: PrimMonad m => Stream m a -> m [a] streamToList2 (Stream step s0) = do mem <- createEmpty let go !n s = do r <- step s case r of Yield a t -> do appendOrWrite mem n a go (n+1) t Skip t -> go n t Done -> freezeTill n mem go 0 s0