Eig*_*lue 1 constructor haskell data-structures
我有几个问题
我正在编写这个名为rope的构造函数,我喜欢这个
data Rope = TextRope{ropeText :: String}
| ConcatRope{rope1 :: Rope, rope2 :: Rope}
| SubRope{subRopetext :: Rope, starting :: Integer, ending :: Integer}
deriving Show
Run Code Online (Sandbox Code Playgroud)
首先,当我制作像这样的TextRope
*Main> let s =TextRope "why"
*Main> s
TextRope {ropeText = "why"}
*Main>
Run Code Online (Sandbox Code Playgroud)
当我这样做时,想要获取构造函数的字符串,这就是为什么我并不确定.
对concat和sub构造函数也很好奇.具体来说,在我看来你正在调用这两个构造函数有事情发生,你正在返回将第1个绳索和第2个绳索连接在一起的结果,我不知道如何描述在这种语言中,你正在定义数据结构但不知何故返回的结果必须由结构计算
以下是这些功能如何工作的一些示例
> let tr = TextRope "Hello,"
> let sr = TextRope " world!"
> let hw = ConcatRope tr sr
> let ow = SubRope hw 4 4
> tr
Hello,
> sr
world!
> hw
Hello, world!
Run Code Online (Sandbox Code Playgroud)
整体混淆,haskell构造函数和数据类型的新东西,所以一些指针会有所帮助(虽然不是c指针!)
数据构造函数永远不会工作.它们只保存您传递给它们的数据.如果你想完成工作,你应该定义所谓的智能构造函数,它们只是在将它传递给实际构造函数之前执行某些操作的函数.一个例子可能是
data Fraction = Fraction
{ numerator :: Int
, denominator :: Int
} deriving (Eq)
(%) :: Int -> Int -> Fraction
x % y =
let (a, b) = reduce x y
in Fraction a b
-- Reduces a fraction to it's simplest terms
reduce :: Int -> Int -> (Int, Int)
reduce num den = undefined
Run Code Online (Sandbox Code Playgroud)
在这里,您不会Fraction
从模块中导出构造%
函数,只是以最简化的形式构造一个的函数.
您遇到的另一个问题是您希望构造函数以不同方式打印出来.你可以通过不推导来实现这一目标Show
.但是,我会警告Haskell约定show . read = read . show = id
,这不符合你想做的事情.但这并不是一个严格的约定,并且没有什么能阻止你做以下事情:
data Rope = <your implementation minus the deriving Show bit>
instance Show Rope where
show (TextRope t) = t
show (ConcatRope r1 r2) = show r1 ++ show r2
show (SubRope r starting ending) = <exercise left to reader>
Run Code Online (Sandbox Code Playgroud)
顺便说一句,我建议不要使用具有不同字段名称的总和类型的记录,这可能会导致程序类型检查的问题,但是如果以不同的方式编写,则包含可在编译时捕获的错误.例如,如果你有代码会发生什么
> ropeText (ConcatRope (TextRope "Hello, ") (TextRope "world!"))
Run Code Online (Sandbox Code Playgroud)
这会导致错误并导致程序崩溃!相反,看起来你只想要一个Rope
带有concat
和subRope
函数的类型,所以你可以非常简单地实现它
data Rope = Rope String deriving (Eq)
concatRope :: Rope -> Rope -> Rope
concatRope (Rope r1) (Rope r2) = Rope (r1 ++ r2)
-- Why use Integer instead of Int? You might find it's easier to implement this function
subRope :: Rope -> Integer -> Integer -> Rope
subRope (Rope r) start end = Rope $ substr start end r
where substr s e text = <exercise left to reader>
Run Code Online (Sandbox Code Playgroud)
现在绝对没有办法进行非法的绳索操作,唯一的区别是现在你必须用concatRope
它代替ConcatRope
和subRope
代替SubRope
.您可以保证这些功能可以满足您的需求,但是您没有一些无法帮助您的复杂类型.
归档时间: |
|
查看次数: |
117 次 |
最近记录: |