我是否正确理解此功能?

时间:2018-12-29 15:11:32

标签: haskell functional-programming

一种族谱可以由以下Haskell数据类型表示:

type Name   = String
type Born   = Int
data Family = Fam Name Born [Family]

这是一个家庭示例:

duck :: Family
duck = Fam "Uncle Scrooge" 1898
                    [ Fam "Donald" 1932 [] ,
                      Fam "Ronald" 1933
                              [ Fam "Huey" 1968 [] ,
                                Fam "Duey" 1968 [] ,
                                Fam "Louie" 1968 [] ]
                    ]

此值代表鸭子家庭的公系,生于1898年的Scrooge叔叔有两个儿子,唐纳德(Donald)和罗纳德(Ronald)。罗纳德(Ronald)有三个孩子。唐纳德(Donald)没有孩子,罗纳德(Ronald)没有孙子。

我的任务是描述以下功能中发生的事情:

parent :: Name -> Family -> [Name]            
parent n fam = par [] fam
  where 
        par fathers (Fam child _ cs)
           | child == n = fathers ++ otherFathers
           | otherwise  = otherFathers
                where otherFathers = concatMap (par [child]) cs
                                  -- concat [par [child] c | c <- cs ]
给出一个人名和一棵家谱的

在树中找到该人的所有可能的父母。例如,

*Main> parent "Duey" duck
[Ronald]

*Main> parent "Uncle Scrooge" duck
[]

*Main> parent "Bob" duck
[]

如果孩子的名字在家族树中多次出现,那么可能会有不止一个父母。

这是我的尝试:

假设我要解决parent "Duey" duck。即将发生的第一件事是我将运行par函数,其输入为[](一个空列表)和duck(其数据类型为{{1} }。

这是我开始感到困惑的地方,请多多包涵。

那么Family函数的作用是什么?据我所知,par函数包含一个列表和一个par。然后,它检查Family起源的名称是否等于我们用作Family输入的名称。如果它们相等,那么它将追加输入的列表和parent。如果名称不相等,则仅返回otherFathers。因此,就目前而言,它检查otherFathers是否等于“ Duey”。由于不是,它将返回"Uncle Scrooge"

那么otherFathers的作用是什么?据我了解,它在家庭的下一个分支上将otherFathers函数与par映射。因此,在我们的情况下,它在["Child"]par ["Uncle Scrooge"]的族上运行"Donald"。由于这两个都不等于"Ronald",因此将重复相同的过程,但使用"Duey"par ["Donald"] []。由于“ Donald”没有家庭,因此该功能无法继续。 par ["Ronald"] cs将像以前一样使用par ["Ronald"] cs"Huey"重复smae过程,在该过程中,由于它们没有任何子代,该功能无法继续。但是使用“ Duey”,因为该名称等于第一个输入的名称,它将在其他父亲中添加“ Ronald”,然后返回[“ Ronald”] ++ otherFathers,因为没有更多的家庭要检查了。 >

这是我的问题:

  1. 我是否正确理解代码?我想念什么吗?
  2. 如果您要在哪里构建此"Louie"函数,那将是您的 策略?

一千感谢任何人花时间阅读和回复,我真的非常感谢。干杯。

我是这个网站的新手,所以希望收到有关格式等方面的任何反馈。

1 个答案:

答案 0 :(得分:3)

是的,您已经正确了解正在发生的事情。

我想我不会这样写代码。令我感到困扰的是,它使用具有0或1个元素的列表( popularImageStyle: { height: 100, width: 100, borderRadius: 10, }, popularImageViewContainer:{ elevation: 3, borderRadius: 10, borderWidth: 1, borderColor: '#000', }, 的{​​{1}}参数)来指示递归是否是“第一步”。对我来说,似乎更直接地独立对待树的每个节点,为与我们正在寻找的人匹配的每个孩子在该节点一次发出名称。应用了这个想法和其他一些美学调整之后,我想我会这样说:

model = Sequential()

model.add(LSTM(
    input_shape=(None, 1),
    units=50,
    return_sequences=True))
model.add(Dropout(0.2))

model.add(LSTM(
    200,
    return_sequences=False))
model.add(Dropout(0.2))

model.add(Dense(units=1))
model.add(Activation('linear'))

model.compile(lose='mse', optimizer='rmsprop')

# Step 3. Train model
model.fit(X_Training, Y_Training,
          batch_size=512,
          nb_epoch=5,
          validation_split=0.05)