片段似乎非常适合将UI逻辑分离为某些模块.但随着ViewPager
它的生命周期对我来说仍然是迷雾.因此迫切需要大师的想法!
见下面的哑解决方案;-)
主要活动有ViewPager
碎片.这些片段可以为其他(子域)活动实现一些不同的逻辑,因此片段的数据通过活动内部的回调接口填充.第一次发布时一切正常,但是!...
当重新创建活动时(例如,在方向改变时),那么ViewPager
碎片也是如此.代码(你会在下面找到)说每次创建活动时我尝试创建一个ViewPager
与片段相同的新片段适配器(也许这就是问题)但FragmentManager已经将所有这些片段存储在某个地方(其中?)和为那些人启动娱乐机制.因此,重新启动机制使用我的回调接口调用来调用"旧"片段的onAttach,onCreateView等,以通过Activity的实现方法启动数据.但是这个方法指向通过Activity的onCreate方法创建的新创建的片段.
也许我使用了错误的模式,但即便是Android 3 Pro也没有太多关于它的内容.所以,请给我一两拳,并指出如何以正确的方式做到这一点.非常感谢!
主要活动
public class DashboardActivity extends BasePagerActivity implements OnMessageListActionListener {
private MessagesFragment mMessagesFragment;
@Override
protected void onCreate(Bundle savedInstanceState) {
Logger.d("Dash onCreate");
super.onCreate(savedInstanceState);
setContentView(R.layout.viewpager_container);
new DefaultToolbar(this);
// create fragments to use
mMessagesFragment = new MessagesFragment();
mStreamsFragment = new StreamsFragment();
// set titles and fragments for view pager
Map<String, Fragment> screens = new LinkedHashMap<String, Fragment>();
screens.put(getApplicationContext().getString(R.string.dashboard_title_dumb), new DumbFragment());
screens.put(getApplicationContext().getString(R.string.dashboard_title_messages), mMessagesFragment);
// …
Run Code Online (Sandbox Code Playgroud) Scala groupBy
在列表上有一个函数,它接受从列表项中提取键的函数,并返回另一个列表,其中的项是由键和生成该键的项列表组成的元组.换句话说,这样的事情:
List(1,2,3,4,5,6,7,8,9).groupBy(_ % 2)
// List((0, List(2,4,6,8)), (1, List(1,3,5,7,9)))
Run Code Online (Sandbox Code Playgroud)
(实际上,它看起来像在当前版本中提供了一个Map
,但这并不重要).C#有一个更有用的版本,可以让你同时映射值(如果你的关键函数只是提取元组的一部分,那么非常有用).
Haskell有一个groupBy
,但它有点不同 - 它根据一些比较函数对事物进行分组.
在我去写它之前,groupBy
在Haskell中是否有相当于Scala的东西?Hoogle对于我希望签名看起来像什么(下图)没有任何东西,但我可能错了.
Eq b => (a -> b) -> [a] -> [(b,[a])]
Run Code Online (Sandbox Code Playgroud) 请考虑以下类型签名:
data Foo x = Foo {
name :: String
, reader :: String -> x
}
instance Functor Foo where
fmap f (Foo n r) = Foo n $ f . r
Run Code Online (Sandbox Code Playgroud)
现在,我显示来自自然转化Foo
到optparse-applicative
的Parser
类型:
import qualified Options.Applicative as CL
mkParser :: Foo a -> CL.Parser a
mkParser (Foo n _) = CL.option CL.disabled ( CL.long n )
Run Code Online (Sandbox Code Playgroud)
(好吧,它有点无用,但它可以用于讨论).
现在我Bar
成为免费的替代函子Foo
:
type Bar a = Alt Foo a
Run Code Online (Sandbox Code Playgroud)
鉴于这是一个免费的仿函数,我应该能够mkParser
从一个自然转变Bar …
我正在尝试读取包含表单的键/值对的文件:
#A comment
a=foo
b=bar
c=baz
Some other stuff
Run Code Online (Sandbox Code Playgroud)
如所建议的那样,有各种其他线路.这想要进入我可以从中查找键的地图.
我最初的方法是读取行并在'='字符上拆分得到一个[[String]]
.在Scala中,我会使用collect
,它接受一个部分函数(在这种情况下类似于\x -> case x of a :: b :: _ -> (a,b)
并在它定义的地方应用它,丢弃函数未定义的值.Haskell有任何等价的吗?
如果不这样做,那么在Haskell中如何做到这一点,无论是沿着我的方向还是使用更好的方法?
假设我有一个选项列表:
let opts = [Some 1; None; Some 4]
Run Code Online (Sandbox Code Playgroud)
我想将这些转换成列表选项,这样:
None
,则结果为None
为这个特定情况(使用Core和Monad
模块)编写它是相对简单的:
let sequence foo =
let open Option in
let open Monad_infix in
List.fold ~init:(return []) ~f:(fun acc x ->
acc >>= fun acc' ->
x >>= fun x' ->
return (x' :: acc')
) foo;;
Run Code Online (Sandbox Code Playgroud)
但是,正如问题标题所暗示的那样,我真的想抽象出类型构造函数而不是专门的Option
.Core似乎使用仿函数来提供更高级别的类型的效果,但我不清楚如何编写要在模块上抽象的函数.在Scala中,我使用隐式上下文绑定来要求某些内容的可用性Monad[M[_]]
.我期待无法隐式传递模块,但我该如何明确地做到这一点?换句话说,我可以写一些近似于此的东西:
let sequence (module M : Monad.S) foo =
let open M in
let open M.Monad_infix in
List.fold ~init:(return []) ~f:(fun …
Run Code Online (Sandbox Code Playgroud) 在Vinyl中,我可以为记录定义类型别名,以便更容易导出到其他模块:
import Data.Vinyl
name = Field :: "name" ::: String
age = Field :: "age" ::: Int
type Person = ["name" ::: String, "age" ::: Int]
Run Code Online (Sandbox Code Playgroud)
现在假设我添加另一个存储高度的字段.
height = Field :: "height" ::: Int
Run Code Online (Sandbox Code Playgroud)
我想很好地为包含Person
和的记录构造一个类型别名height
.天真,这可能看起来像这样:
type MeasuredPerson = ("height" ::: Int) : Person
Run Code Online (Sandbox Code Playgroud)
显然,这种语法不起作用!有没有办法做到这一点?是否有任何好的参考资料来解释这里似乎使用的类型级数组语法?
假设我有以下课程:
class P a where
nameOf :: a -> String
Run Code Online (Sandbox Code Playgroud)
我想声明这个类的所有实例都是自动的实例Show
.我的第一次尝试将如下:
instance P a => Show a where
show = nameOf
Run Code Online (Sandbox Code Playgroud)
昨天我第一次尝试这种方式导致了一个语言扩展的兔子:我首先被告知要打开灵活的实例,然后是不可判定的实例,然后重叠实例,最后得到关于重叠实例声明的错误.我放弃了并重新开始重复代码.然而,从根本上说,这似乎是一个非常简单的需求,应该很容易满足.
那么,有两个问题:
UndecidableInstances
理解为什么我可能需要,因为我似乎违反了帕特森的条件,但这里没有重叠的实例:P
甚至没有实例.为什么typechecker认为有多个实例Show Double
(在这个玩具示例中似乎就是这种情况)?编辑:这个问题最初是针对特定的.我仍然宁愿有一个bash解决方案,但如果有一个很好的方法在另一个shell中执行此操作,那么这也是有用的知识!
好的,问题的顶级描述.我希望能够为bash添加一个钩子,例如,当用户输入时$cat foo | sort -n | less
,它会被拦截并翻译成wrapper 'cat foo | sort -n | less'
.我已经看到了在每个命令之前和之后运行命令的方法(使用DEBUG陷阱或PROMPT_COMMAND或类似命令),但没有关于如何拦截每个命令并允许它由另一个进程处理的方法.有没有办法做到这一点?
为了解释我为什么要这样做,以防人们有其他方法来处理它:
像脚本这样的工具允许您将终端中执行的所有操作记录到日志中(在某种程度上,可以记录历史记录).然而,他们做得不是很好 - 脚本将输入与输出混合成一个大字符串,并与诸如vi等接管屏幕的应用程序混淆,历史记录只给出输入的原始命令,并且它们都不起作用好吧,如果您同时输入多个终端的命令.我想要做的是捕获更丰富的信息 - 例如,命令,执行的时间,完成的时间,退出状态,stdin和stdout的前几行.我也更喜欢将它发送到一个可以愉快地复用多个终端的监听守护进程.执行此操作的简单方法是将命令传递给另一个程序,该程序可以执行shell以处理作为子进程的命令,同时获取stdin,stdout,退出状态等的句柄.可以写一个shell来执行此操作,但是你' d失去了bash中的大部分功能,这会很烦人.
这样做的动机来自于试图理解探索性数据分析,就像事后的程序一样.有了这样更丰富的信息,就可以生成关于发生的事情的正确报告,将一个命令的多个调用压缩到一个命令,其中前几个命令给出非零退出,通过搜索触及文件的所有内容来询问文件来自何处,等等
我正在尝试编写一个日志记录shell; 例如,捕获有关以结构化格式运行的命令的数据.为此,我正在使用readline
读取命令,然后在子shell中执行它们,同时捕获诸如所花费的时间,环境,退出状态等内容.
到现在为止还挺好.然而,最初的尝试运行的东西,如vi
或less
从内部此日志壳失败.调查表明要做的事情是建立一个伪tty并将子壳连接到那个而不是普通管道.这会阻止vi抱怨没有连接到终端,但仍然失败 - 我在屏幕上打印了一些废话并且命令在编辑器中作为字符打印 - 例如"ESC"只显示^[
.
我认为我需要做的是将pty置于原始模式.为此,我尝试了以下方法:
pty <- do
parentTerminal <- getControllingTerminalName >>=
\a -> openFd a ReadWrite Nothing defaultFileFlags
sttyp <- getTerminalAttributes parentTerminal
(a, b) <- openPseudoTerminal
let rawModes = [ProcessInput, KeyboardInterrupts, ExtendedFunctions,
EnableEcho, InterruptOnBreak, MapCRtoLF, IgnoreBreak,
IgnoreCR, MapLFtoCR, CheckParity, StripHighBit,
StartStopOutput, MarkParityErrors, ProcessOutput]
sttym = withoutModes rawModes sttyp
withoutModes modes tty = foldl withoutMode tty modes
setTerminalAttributes b sttym Immediately
setTerminalAttributes a sttym Immediately
a' <- …
Run Code Online (Sandbox Code Playgroud) 下面是一些使用实现了小型接收服务器代码conduit
,network-conduit
和stm-conduit
.它在套接字上接收数据,然后通过STM通道将其流式传输到主线程.
import Control.Concurrent (forkIO)
import Control.Concurrent.STM (atomically)
import Control.Concurrent.STM.TBMChan (newTBMChan, TBMChan())
import Control.Monad (void)
import Control.Monad.IO.Class (MonadIO (liftIO))
import Control.Monad.Trans.Class
import Data.ByteString (ByteString)
import qualified Data.ByteString as B
import Data.Conduit
import qualified Data.Conduit.Binary as DCB
import Data.Conduit.Extra.Resumable
import Data.Conduit.Network (sourceSocket)
import Data.Conduit.TMChan (sinkTBMChan, sourceTBMChan, mergeSources)
import System.Directory (removeFile)
import System.IO
type BSChan = TBMChan ByteString
listenSocket :: Socket -> Int -> IO BSChan
listenSocket soc bufSize = do
chan <- atomically $ newTBMChan bufSize …
Run Code Online (Sandbox Code Playgroud)