在WinHugs中,我实现了以下函数:
map :: (a -> b) -> [a] -> [b]
map f [] = []
map f (x:l) = f x : map f l
这只需为列表中的每个数字运行一个函数,如下所示:
Hugs> map (+ 1) [1,2,3]
应给予
[2,3,4].
但是当我尝试加载*.hs脚本时,WinHugs给出了错误消息
ERROR file:.\script.hs:3 - Ambiguous variable occurrence "map"
*** Could refer to: Main.map Hug
在GHCi中:(>表示输出)
data Unit = Unit
let x = Unit
let y = ()
:p x
> x = (_t1::Unit)
:p y
> y = ()
:i ()
> data () = () -- Defined in `GHC.Tuple'
为什么Unit和()的行为不同?还有其他类似于()的类型,例如Int和Char。还有其他这样的类型吗?
令人惊讶的是,当我将()替换为undefined时,它的行为再次与我预期的一样:
let y = undefined :: ()
:p y
y = (_t2::())
如果我们有两个函数,f和g,那么在Haskell中h = f . g相当于h x = f(g x)。也就是说,函数从右到左应用到输入。它为什么从右到左,而不是从左到右,有什么根本原因吗?也就是说,他们为什么不让h = f . g与h x = g(f x)等价呢?
编辑:就像其他人指出的那样,我的等效函数出现了错误的地方,所以我修正了它们。
目前,我正尝试用“学习Haskell”一书来学习Haskell,并试图了解flip函数在中的实现。问题是,作者指出,如果g x y = f y x是有效的,那么f y x = g x y也必须是真。但是,这种逆转是如何和为什么影响这两个函数定义的呢?
我知道currying是如何工作的,我也知道->操作符在默认情况下是正确关联的,所以类型声明实际上是相同的。我也了解彼此之间的功能,但不了解g x y = f y x的反转与此之间的关系。
第一翻转函数
flip' :: (a -> b -> c) -> (b -> a -> c)
flip'
如果我将以下2行放入foobar.hs
f 1 = 1
f x = f (x-1)
然后
$ ghci
> :load foobar.hs
> f 5
1
但如果我做了
$ ghci
> let f 1 = 1
> let f x = f (x-1)
> f 5
^CInterrupted.
然后它就不会回来了。为什么?
我正在学习一个教程,并有以下类型定义:
data Point = Point Float Float deriving (Show)
data Shape = Circle Point Float | Rectangle Point Point deriving (Show)
将包含这些定义的文件加载到ghci中,并希望使用
surface :: Shape -> Float
我得到错误消息变量,而不是作用域: surface ::Shape -> Float。
我甚至不知道我在哪里有一个变量,更不用说我为什么会有这个错误了!任何帮助都非常感谢。
我在haskell中有这行代码,其中level :: Float和y :: Int,
mod (floor(fromIntegral y + (level/2))) (floor level)
ghci返回给我以下内容:
No instance for (Integral Float)
arising from a use of `mod'
Possible fix: add an instance declaration for (Integral Float)
例如,我使用fromIntegral和floor尝试了几个版本
mod (( y + (floor $ level/2
max' :: Int -> Int -> Int
max' a b = if a >= b then a else b
你看这个函数是正确的,但是如果我写
let a = 3,
let b = 3
而且如果我写
ghci> a == b => True
所以它比较它们,为什么它在我的函数中没有比较
ghci> max' a b
为什么会发生错误?或者写它的正确方法是什么?
对不起,我是初学者,如果我的问题很傻,请原谅我,如果有必要,请编辑它,谢谢
<interactive>:19:6:
Couldn'
我在Haskell中有以下两个类型签名:
foo :: (a -> (a,b)) -> a -> [b]
bar :: (a -> b) -> (a -> b -> c) -> a -> c
我想编写这两个函数的具体实现,但我真的很难理解从哪里开始。
我知道foo接受一个函数(a -> (a,b))并返回a和一个包含b的列表。
bar接受函数(b -> c),该函数返回函数(a -> b -> c),该函数最终返回a和c。
谁能给我举一个具体实现的例子?
我如何知道从哪里开始做这样的事情,以及定义的左侧是什么?
我现在正在读一本关于Haskell并行编程的书。在这里,我看到了这样一个例子:
Prelude> let x = 2 + 3
Prelude> :sp x
x = _
Prelude> x
5
Prelude> :sp x
x = 5
但是,在我来自平台Haskell 2014.02的GHCi 7.8.3中,我得到了这样的行为:
Prelude> let x = 2 + 3
Prelude> :sp x
x = _
Prelude> x
5
Prelude> :sp x
x = _
看最后一行。为什么x没有被评估?我尝试使用"seq ()
我试图利用Semigroup类型化来玩玩单子,并且我试图在自然数上定义一个单子。我将以下类和实例声明放入GHCI中
Prelude:{
Prelude| class Semigroup a where
Prelude| (<>) :: a -> a -> a)
Prelude| newtype Sum a = Sum { getSum :: a }
Prelude| deriving (Eq, Ord, Show)
Prelude| instance Num a => Monoid (Sum a) where
Prelude| (<>
我就是这么做的 reverseP x = pour x []
where pour [] ans = ans
pour (h:t) ans = pour t (h:ans) 其中参数累加器比原始且昂贵的版本更好 reverse [] = []
reverse (h:t) = reverse t ++ [h] 但后来我想看看我能不能重做 使用 只是一个练习。我终于让它起作用了 reverseP2 x =
let
(t:ts) = x
pour [] ans = ans
pour (t:ts) ans = pour ts (t:ans)
与相关的是,当我将代码与uniplate包一起使用时,我遇到了使代码泛化的问题。我正在处理模块中的数据结构,它们都是带有类型参数l的泛型。这个l在整个树中是相同的。
我正在编写的代码是这样的:
doInt :: Child1 l -> Child1 l
doInt (Child1 l n) = Child1 l (n + 1)
doString :: Child2 l -> Child2 l
doString (Child2 l (_:s)) = Child2 l ('j' : s)
replace :: Data l => Parent l ->
我花了一个小时来处理一个Haskell错误,然后追踪到它使用了一个特定的函数名it。谁能解释一下为什么函数名fu和it在下面的文字记录中表现不同?具体地说,为什么it的类型在被调用时会发生变化? λ> fu x = x + 1
λ> :t fu
fu :: Num a => a -> a
λ> fu 1
2
λ> :t fu
fu :: Num a => a -> a
λ> it x = x + 1
λ> :t it
it :: Num a => a -> a
λ> it 1
2
λ> :t it
it ::
我试图在Haskell中定义一个可折叠的实例,并且我在导入方面遇到了一些问题。
所以首先尝试:模块MyList
import Data.Foldable
data MyList a = MyList [a]
instance Foldable (MyList) where
foldr f b (MyList as) = foldr f b as
结果(正常但烦人)
模棱两可的事件“`foldr”
所以,我想我必须把它隐藏在前奏:模块MyList中
import Prelude hiding (foldr)
import Data.Foldable
data MyList a
我如何理解return 1 getLine语句?它通过类型检查,并且似乎与1相同。getLine和return是如何“取消”对方的?对我来说一点意义都没有。
Prelude> :t return 1
return 1 :: (Monad m, Num a) => m a
Prelude> :t return 1 getLine -- why is it not a type error?
return 1 getLine :: Num t => t
Prelude> return 1 getLine
我试图完成Haskell九十九个问题的问题8,但是我有一些问题,理解为什么我的函数的列表结果排序错误。
compress函数的目的是从输入列表中消除任何重复字母,并输出另一个包含唯一字母的列表,这些字母按照它们首次出现在输入列表的顺序排列。以下是压缩函数的代码:
compress l = foldr f [] l where f a b = if a `elem` b then b else a : b
它在重复字母相邻时正确工作,因此"aaaabbb“输出"ab”--这是正确的--然而,当一个复文被另一个字母隔开时,它改变了它在输出中的顺序,因此"aba“输出了
这个不错,没问题
Prelude> read "8.2" + 3.4
11.6
但是这个不行。
Prelude> read "8.2"+"3.4"
<interactive>:69:11:
No instance for (Num [Char]) arising from a use of ‘+’
In the expression: read "8.2" + "3.4"
In an equation for ‘it’: it = read "8.2" + "3.4&
是否有方法将字符“+”、“-”、“*”、“/”转换为相应的函数?我的意思是像这样的函数(很明显,我试过了,但没有起作用):
toOperator :: Num a => String -> a -> a -> a
toOperator c = read c :: Num a => a -> a -> a
我有模块:
module Writer where
import Prelude hiding (Monad, (>>=), return, (=<<))
main = putStrLn "hello"
class Monad m where
return :: a -> m a
(>>=) :: m a -> (a -> m b) -> m b
(=<<) :: (a -> m b) -> m a -> m b
(=<<) = flip (>>
我正在从赫顿的书“Haskell中的编程”(第二版)中学习Haskell。开始的时候。7 .“高阶函数”,函数“两次”的定义为:
twice :: (a -> a) -> a -> a
twice f x = f (f x)
然后给出了几个使用示例,例如:
> twice reverse [1,2,3]
[1,2,3]
然后作者说,“将一个(有限)列表反转两次没有任何效果的事实被方程二次反向=id.”当我开始写作时:
GHCi, version 8.4.4: http://www.haskell.org/ghc/ :? for help
Prelude> :ty
下面的代码是否重载了Num和Fractional类中的操作符?在我看来,除了第一次出现操作签名的地方之外,不可能在类中重载一个操作。
我看过一个。
module Numbers where
import qualified Prelude as P
class Number a where
(+), (-), (*) :: a -> a -> a
sqr, sqrt:: a -> a
instance Number P.Float where
(+) a b = a P.+ b
(-) a b
我发现
Prelude> :i ()
data () = () -- Defined in `GHC.Tuple'
instance Bounded () -- Defined in `GHC.Enum'
instance Enum () -- Defined in `GHC.Enum'
instance Eq () -- Defined in `GHC.Classes'
instance Ord () -- Defined in `GHC.Classes'
instance Read () -- Defined in `GHC.Read
我只是想看看WinGHCi是否适用于Haskell编程,但我不知道为什么会显示上面的错误。 我不知道这是否是在Haskell上工作的正确应用程序,如果您知道另一个可以实际工作的应用程序,我将不胜感激。 f (x:xs) = f ys ++ [x] ++ f zs
where
ys = [a | a ← xs, a ≤ x]
zs = [b | b ← xs, b > x] <interactive>:21:20: error:
parse error on input ‘=’
Perhaps you need a 'let' in a
在Haskell中,为什么forever的类型签名
forever :: Monad m => m a -> m b
具体来说,为什么不只是:: Monad m => m a -> m a?当然,我们所采取行动的单一模式不会在forever中途改变。
职能,如:
forever' :: Monad m => m a -> m a
forever' = forever
似乎是完全一样的。