NB:我在下面定义的类型只是用于此问题的一个方便示例;我确定没有必要让我在Haskell中推出自己的复数定义。
我不知道我是否在这里使用了正确的术语,但下面的选择器<section>
<div class="contact-us-title">
<h1>Contact Us</h1>
</div>
<form class="contact-us-form" name="contactUsForm" ng-submit="vm.processContactForm()">
<div class="form-group">
<input placeholder="name" type="text" name="name" ng-model="vm.name" class="form-control" required />
<span class="label label-danger" ng-show="vm.submitted && contact-us-form.name.$error.required">Required!</span>
</div>
<div class="form-group">
<input placeholder="Email" type="email" name="email" ng-model="vm.email" class="form-control" required />
<span class="label label-danger" ng-show="vm.submitted && contact-us-form.email.$error.required">Required!</span>
<span class="label label-danger" ng-show="vm.submitted && contact-us-form.$error.email">Invalid email!</span>
</div>
<div class="form-group">
<input name="headline" placeholder="Headline" type="text" ng-model="vm.headline" class="form-control" required/>
<span class="label label-danger" ng-show="vm.submitted && contact-us-form.headline.$error.required">Required!</span>
</div>
<div class="form-group">
<textarea name="message" placeholder="Message" type="textbox" ng-model="vm.message" class="form-control" required></textarea>
<span class="label label-danger" ng-show="vm.submitted && contact-us-form.subjectList.$error.required">Required!</span>
</div>
<input type="submit" id="submit-contact-form-btn">
</form>
</section>
是我所说的部分&#34;记录选择器:
r
data Complex = Polar { r :: Float, y :: Float }
| Rectangular { x :: Float, y :: Float }
deriving Show
是&#34; partial&#34;因为它无法应用于所有 r
值; e.g。
Complex
...但
r $ Polar 3 0
-- 3.0
然而,在这种情况下,r $ Rectangular 3 0
-- *** Exception: No match in record selector r
有一个合理的定义,即:
r $ Rectangular x y
GHCi拒绝-- assuming {-# LANGUAGE RecordWildCards #-}
r :: Complex -> Float
r Rectangular { .. } = sqrt $ (x * x) + (y * y)
的此定义,但出现r
错误。
有没有办法扩展multiple declarations of ‘r’
,以便它可以应用于任何 r
值?
当然,我意识到我可以定义像
这样的东西Complex
...但我想知道是否可以扩展现有的选择器-- assuming {-# LANGUAGE RecordWildCards #-}
modulus :: Complex -> Float
modulus Polar { .. } = r
modulus Rectangular { .. } = sqrt $ (x * x) + (y * y)
。
答案 0 :(得分:5)
不,首先应该永远不要引入IMO这样的唱片选择器。我把它写成
type ℝ = Float -- Note that Double is usually more sensible
newtype S¹ = S¹ {ϑ :: ℝ} -- in [-π, π[
newtype ℝPlus = ℝPlus {posℝ :: ℝ} -- in [0, ∞[
data Complex = Polar ℝPlus S¹
| Rectangular ℝ ℝ
deriving Show
这样,部分记录选择器的形式没有潜在的错误,也没有混淆解压缩等等。即使对于这样的“非记录类型”,你也可以编写自己的访问器,最好以镜头形式:
import Control.Lens
r :: Lens' Complex ℝPlus
r = lens get set
where get (Polar r _) = r
get (Rectangular x y) = ℝPlus . sqrt $ x^2 + y^2
set (Polar _ θ) r = Polar r θ
set (Rectangular x y) (ℝPlus r) = Rectangular (x * η) (y * η)
where η = r / sqrt (x^2 + y^2)