我写这个有什么区别?
data Book = Book Int Int
Run Code Online (Sandbox Code Playgroud)
与
newtype Book = Book (Int, Int) -- "Book Int Int" is syntactically invalid
Run Code Online (Sandbox Code Playgroud) 在Haskell中,我认为可以以这样的方式对类型进行别名,即编译器不允许别名类型和非混淆类型之间的引用.根据这个堆栈溢出问题,可以newtype像这样使用Haskell :
newtype Feet = Feet Double
newtype Cm = Cm Double
Run Code Online (Sandbox Code Playgroud)
where Feet和Cm将表现为Double值,但尝试乘以Feet值和Cm值将导致编译器错误.
编辑:Ben在评论中指出,Haskell中的上述定义是不够的.Feet并且Cm将新的类型,其上不会有定义的功能.做了一些研究,我发现以下内容可行:
newtype Feet = Feet Double deriving (Num)
newtype Cm = Cm Double deriving (Num)
Run Code Online (Sandbox Code Playgroud)
这将创建一个从现有Num类型派生的新类型(需要使用switch :) -XGeneralizedNewtypeDeriving.当然,这些新类型会更有价值获得从其他类型,比如Show,Eq等等.但这是正确评价所需的最低Cm 7 * Cm 9.
Haskell和Scala都有type,它只是将现有类型别名化,并允许在Scala中使用无意义的代码,例如此示例:
type Feet = Double
type Cm = Double
val widthInFeet: Feet = 1.0
val widthInCm: Cm = …Run Code Online (Sandbox Code Playgroud) 我很难理解为什么这两个片段在所谓的"穷人严格分析"下会产生不同的结果.
第一个示例使用data(假设一个正确的Applicative实例):
data Parser t a = Parser {
getParser :: [t] -> Maybe ([t], a)
}
> getParser (pure (,) <*> literal ';' <*> undefined ) "abc"
*** Exception: Prelude.undefined
Run Code Online (Sandbox Code Playgroud)
第二个用途newtype.没有其他区别:
newtype Parser t a = Parser {
getParser :: [t] -> Maybe ([t], a)
}
> getParser (pure (,) <*> literal ';' <*> undefined ) "abc"
Nothing
Run Code Online (Sandbox Code Playgroud)
literal x是一个解析器,如果其参数与第一个标记匹配,则成功使用一个输入标记.所以在这个例子中,它失败了因为;不匹配a.但是,该data示例仍然看到下一个解析器未定义,而newtype示例则没有.
我正在学习带有箭头Arrow的教程编程。我已经根据论文输入了以下代码,除了的SF定义是由data,而不是论文中所定义的newtype(实际上,由于我是从内存中键入代码的,所以我偶然地做了此更改):
import Control.Category
import Control.Arrow
import Prelude hiding (id, (.))
data SF a b = SF { runSF :: [a] -> [b] } -- this is the change, using data instead of newtype as in the paper
-- The folowing code is the same as in the paper
instance Category SF where
id = SF $ \x -> x
(SF f) . (SF g) = SF $ …Run Code Online (Sandbox Code Playgroud) 我正在通过为comm语言实现一个简单的解释器来学习如何在Haskell中使用Arrows 。
我有一个eval函数,该函数将一个表达式求值为一个值,但是当输入任何表达式时,eval会无限期地循环。
-- Interp.hs
eval :: A Expr Val
eval = proc e -> case e of
Lit x -> returnA -< Num x
Var s -> do
lookup -< s
Add e1 e2 -> do
v1 <- eval -< e1
v2 <- eval -< e2
case (v1, v2) of
(Num x, Num y) -> returnA -< Num (x + y)
Run Code Online (Sandbox Code Playgroud)
在GHCI中执行此操作会导致无限循环
*Interp> unpack eval M.empty (Lit 1)
Run Code Online (Sandbox Code Playgroud)
在添加表达式的情况下注释掉eval确实会导致表达式给出结果
例如
-- Interp.hs
eval :: A Expr Val …Run Code Online (Sandbox Code Playgroud)