模块GHC/Base.hs包含以下运算符定义:
($) :: forall r a (b :: TYPE r). (a -> b) -> a -> b
f $ x = f x
Run Code Online (Sandbox Code Playgroud)
r意思?(a -> b) -> a -> b笼统吗?TYPE?资料来源:格雷厄姆·赫顿。“ Haskell 编程”(第 180 页)
\n\n\n\n
\n- 使用
\ngetCh,定义一个readLine :: IO String与 getLine 行为方式相同的操作,不同之处在于它还允许使用删除键删除字符。
\n\n提示:删除字符为
\n\xe2\x80\x99\\ DEL\xe2\x80\x99,光标后移一格的控制字符为\xe2\x80\x99\\b\xe2\x80\x99。
我使用一个\'\\b\'角色解决了这个练习,但在网上发现解算器使用了两个角色。为什么这个问题的解决者使用"\\b \\b"而不是"\\b"?似乎是一个错字,但我不确定。我发现它适用于三个\'\\b\'角色。
这个角色是如何运作的?
\nimport System.IO\n\ngetCh :: IO Char\ngetCh = do\n hSetEcho stdin False\n x <- getChar\n hSetEcho stdin True\n return x\n\nreadLine :: IO String\nreadLine = readLine\' ""\n\nreadLine\' :: String -> IO String\nreadLine\' xs = do\n x <- getCh\n case …Run Code Online (Sandbox Code Playgroud) 我有以下定义:
fibs = 1 : scanl (+) 1 fibs
scanl :: (a -> b -> a) -> a -> [b] -> [a]
scanl f q ls =
q : (case ls of
[] ->[]
x:xs -> scanl f (f q x) xs
)
take :: Int -> [a] -> [a]
take n _ | n <= 0 = []
take _ [] = []
take n (x:xs) = x : take (n-1) xs
Run Code Online (Sandbox Code Playgroud)
我想减少以下表达式:
take 3 (fibs)
Run Code Online (Sandbox Code Playgroud)
所以,我会继续:
take 3 …Run Code Online (Sandbox Code Playgroud) 我有这对函数
(,) <$> length :: Foldable t => t a -> b -> (Int, b)
Run Code Online (Sandbox Code Playgroud)
和,
head :: [a] -> a
Run Code Online (Sandbox Code Playgroud)
我想了解的类型
(,) <$> length <*> head
Run Code Online (Sandbox Code Playgroud)
在(<*>) :: Applicative f => f (a -> b) -> f a -> f b类型签名中,
f :: (->) [a]
a :: b
b :: (Int -> b)
因此,实例化类型将是:
(->) [a] (Int, b)
Run Code Online (Sandbox Code Playgroud)
但是,我发现它的类型确实是:
(->) [a] (Int, a)
Run Code Online (Sandbox Code Playgroud)
两个问题,如果可以的话:
b切换为a?资料来源:格雷厄姆·赫顿。“ Haskell 编程”(第 267 页)
- 通过给出fold、foldMap、foldr、foldl 和traverse 的显式定义,展示如何使 Maybe 类型可折叠和可遍历。
我做了foldr定义。为了检查我的解决方案,我在网上找到了这段代码:
-- foldr :: (a -> b -> b) -> b -> Maybe a -> b
foldr _ _ Nothing = mempty
foldr f v (Just a) = f a v
Run Code Online (Sandbox Code Playgroud)
看来累加器应该在基本情况下返回(而不是mempty)。是对的吗 ?
资料来源:格雷厄姆·赫顿。“ Haskell 编程”(第 267 页)
- 使用foldMap,在可与任何可折叠类型一起使用的列表上定义高阶函数过滤器的通用版本:
filterF :: Foldable t => (a -> Bool) -> t a -> [a]
我正在做这个练习并有一些问题:
filterF :: Foldable t => (a -> Bool) -> t a -> t a?过滤器不是应该保留容器的结构吗?这是我的尝试;这是对的吗 ?我应该限制Monoid吗t?
filterF :: Foldable t => (a -> Bool) -> t a -> t a
filterF p = foldMap (\x -> if p x then pure x else mempty)
Run Code Online (Sandbox Code Playgroud) foldr :: (a -> b -> b) -> b -> [a] -> b
foldr f v [] = v
foldr f v (x:xs) = f x (foldr f v xs)
Run Code Online (Sandbox Code Playgroud)
foldl :: (a -> b -> a) -> a -> [b] -> a
foldl f v [] = v
foldl f v (x:xs) = foldl f (f v x) xs
Run Code Online (Sandbox Code Playgroud)
我正在尝试了解这两个功能。我有两个问题。一是关于功能f。一般来说,
foldr f v xs
Run Code Online (Sandbox Code Playgroud)
f可以访问第一个元素xs和递归处理的尾部。这里:
foldl f v xs
Run Code Online (Sandbox Code Playgroud)
f可以访问 xs 的最后一个元素和递归处理的尾部。
这是一种有用(且正确)的思考方式吗? …
如果我对以下表达式进行 beta-reduce:
foldr (mappend . Sum) 1 [2]
= (mappend . Sum) 2 (foldr (mappend . Sum) 1 [])
= (mappend . Sum) 2 1
= mappend (Sum 2) 1
...
Run Code Online (Sandbox Code Playgroud)
查看类型:
// mappend (<>) :: Monoid a => a -> a -> a
Run Code Online (Sandbox Code Playgroud)
我们可以看到最后一行有一个类型错误,因为常量1应该属于Monoid类(但事实并非如此)。
不过,ghci并不抱怨。
为什么要检查表达式类型?
对chr 232回报的评估'\232'而不是'è'.
当然,我期待(chr . ord) 'è'回来'è'。相反,我得到了'\232'
有人可以解释这里发生了什么吗?
看看这个定义出现在Data.Tree:
foldTree :: (a -> [b] -> b) -> Tree a -> b
foldTree f = go where
go (Node x ts) = f x (map go ts)
Run Code Online (Sandbox Code Playgroud)
我的具体问题是:当goname 出现在方程的右侧(map go ts)时,函数的类型如何
(a -> [b] -> b)
Run Code Online (Sandbox Code Playgroud)
被推断?
例如,有这行代码:
foldTree (:) (Node 1 [Node 2 []])
Run Code Online (Sandbox Code Playgroud)
实例化定义:
foldTree (:) = go where
go (Node 1 [Node 2 []]) = (:) 1 (map go [Node 2 []])
Run Code Online (Sandbox Code Playgroud)
(:) 1 (map go [Node 2 []])没有完全评估,所以我只看到 …