我想做这个功能
addAndDrop x y = x + 1
Run Code Online (Sandbox Code Playgroud)
点免费.我明白这一点:
addAndDrop x y = (+1) x
Run Code Online (Sandbox Code Playgroud)
但是从这里我可以采取两种不同的途径.
--First path:
addAndDrop x y = const ((+1) x) y
addAndDrop x = const ((+1) x)
addAndDrop x = (const . (+1)) x
addAndDrop = const . (+1) --I'm done!
--Second path:
addAndDrop x y = (+1) (const x y)
addAndDrop x y = ((+1) . (const x)) y
addAndDrop x = (+1) . (const x) --Here I'm stuck!
Run Code Online (Sandbox Code Playgroud)
在第一条道路上一切顺利.但在第二条道路上,我陷入困境.
有没有办法继续并完成第二条路径,或者我真的卡住了,因为我认为我是?
如果我真的被卡住了,是否有任何基本的幻想,数学/功能/无论什么原因导致我陷入一条路而不是另一条路?
代码
default ()
h :: Bool
h = 1.0 == 1.0 --Error. Ambiguity.
Run Code Online (Sandbox Code Playgroud)
不编译.这是预料之中的,因为存在歧义.它可能是Float
或者Double
和Haskell不知道我们想要哪一个.
但是代码
default ()
foo :: (Fractional a, Eq a) => a -> Bool
foo x = x == 1.0
Run Code Online (Sandbox Code Playgroud)
编译成功.我不完全明白为什么.为什么这也不明确?
我有一种感觉,这是因为每当我们打电话foo
,我们都保证到位的已经选择了一个具体类型a
,即,我们都保证有固定a
要么Float
或Double
(有两个实例,或者我们的自定义类型Fractional
和Eq
编译) - 时间,因此没有歧义.
但这只是一种感觉,我不知道它是否100%准确.
如果有其他好的选择,为什么还没有具有随机访问的所有共同特征的类型类?然后,Vector和其他随机访问数据结构将具有该类型类的实例.
在下面的代码,我如何检查-只有通过增加旁边一个班轮if
-是否foo
是Yes
?
data Asdf = Yes | No | Other
foo :: Asdf
foo = Yes
hello :: String
hello =
if <check if foo is Yes> -- How?
then "foo is Yes"
else "foo isn't Yes"
Run Code Online (Sandbox Code Playgroud)
我知道我可以使用case
,但这个问题的关键是以某种方式得到Bool
它.这对我在单元测试等方面很有用(case
可能会很快变得非常混乱.)
看到这两个问题:
--I don't want any defaulting. For example, I don't want
--a general Num to convert to Double deep within my codebase.
--I want to keep my codebase as general as possible.
--Only in main, where I actually call my pure functions,
--do I want to specify an actual, concrete type.
default ()
f :: RealFloat a => a
f = undefined
g :: Bool
g = let
foo :: RealFloat a => a --First question: Why do I even …
Run Code Online (Sandbox Code Playgroud) 此代码正常工作正常:
data Heh a = Heh a
instance (Eq a) => Eq (Heh a) where
(Heh a1) == (Heh a2) = a1 == a2
Run Code Online (Sandbox Code Playgroud)
然而这给出了一个错误:
data Heh a = Heh a
instance (Eq a) => Eq (Heh a) where
(Heh a1) == (Heh a2) = (a1 :: a) == a2
-- Error: Couldn't match expected type ‘a1’ with actual type ‘a’
-- ...
Run Code Online (Sandbox Code Playgroud)
唯一的变化是添加:: a
.
但为什么会失败呢?是不是a1
真的a
?还有什么可能呢?
这与此forall
有何关系?我理解Haskell有一个forall
关键字来处理这个问题.(顺便说一下,如果在GHC 8.0之前无法实现这一点,请随时告诉我如何在即将推出的GHC 8.0中进行操作.)
data Car = Car { carName :: String, carFunctionality :: ByteString }
main :: IO ()
main = do
complexFunctionality <- undefined -- create complex functionality
let myCar = Car {
carName = "myCar",
carFunctionality = complexFunctionality }
-- A) Call functions that use myCar, but only use carName.
-- They don't use the carFunctionality.
-- B) From here on, myCar is never again used.
Run Code Online (Sandbox Code Playgroud)
问题:
一旦达到 B),垃圾收集器(下次触发时)会收集吗myCar
?我自己可以回答这个问题。答案显然是肯定的,因为这就是 GC 的全部意义。
更重要的问题。在A)中的函数调用期间,是否存在complexFunctionality
仅仅因为没有被使用而被收集的风险?换句话说,我想知道一个对象 ( complexFunctionality
) 是否有可能在周围的对象被收集之前被myCar …
我可以这样创建Num a => a
:
foo :: Num a => a
foo = 2
Run Code Online (Sandbox Code Playgroud)
同样对于任何其他数字类:
foo :: Fractional a => a
foo = 2.0
Run Code Online (Sandbox Code Playgroud)
但是,我不能想办法创造型的东西Eq a => a
,Ord a => a
或任何非数(不使用undefined
).
在我看来,数字在这方面是特殊的.
是吗?