递归方案是否有一个名字,就像一个变形,但是可以在运行时查看最终结果?这是一个精心设计的示例:
toPercents :: Floating a => [a] -> [a]
toPercents xs = result
where
(total, result) = foldr go (0, []) xs
go x ~(t, r) = (x + t, 100*x/total:r)
{-
>>> toPercents [1,2,3]
[16.666666666666668,33.333333333333336,50.0]
-}
Run Code Online (Sandbox Code Playgroud)
该示例total在折叠的每一步都使用,即使直到结束时才知道其值。(显然,这取决于工作的懒惰。)
考虑这些不同的尝试,例如last:
Prelude> import Data.Foldable
Prelude Data.Foldable> foldr const undefined (reverse [1,2,3])
3
Prelude Data.Foldable> foldr' const undefined (reverse [1,2,3])
3
Prelude Data.Foldable> foldl (flip const) undefined [1,2,3]
3
Prelude Data.Foldable> foldl' (flip const) undefined [1,2,3]
*** Exception: Prelude.undefined
CallStack (from HasCallStack):
error, called at libraries/base/GHC/Err.hs:79:14 in base:GHC.Err
undefined, called at <interactive>:5:21 in interactive:Ghci4
Run Code Online (Sandbox Code Playgroud)
这对我来说是有道理的,foldl而且foldr两者都有效,因为它们对累加器并不严格,而对我来说不严格是有道理的foldl',因为它是。但为什么foldr'有效?它的累加器不应该也很严格吗?
我正在绘制一个小的 C++ 程序,它将把数组传递给 Lua 并在那里修改它们,我打算在程序中读取一个 lua 脚本,这样我就可以修改它而无需重新编译程序
我的第一个障碍是确保 Lua 能够修改已经分配的数组,而不是在 Lua 空间中再次分配它们。数据将是浮动的,并且大小会非常大,但我现在从很小的地方开始。
为了简化这个接口,我尝试了 LuaBridge 2.6,但它没有提供预期的结果。下面是一个完全“工作”的程序。
#include <iostream>
#include <cstdint>
#include <cstring>
#include <vector>
#include <lua5.3/lua.hpp>
#include <LuaBridge/LuaBridge.h>
int main(void)
{
const uint32_t LENGTH = 512 * 256;
std::vector <float> input(LENGTH),
output(LENGTH);
memset(output.data(), 0, LENGTH * sizeof(float)); // Zero the output
for(uint32_t i = 0; i < LENGTH; i++) // Populate input
input[i] = (float)i + 0.5f;
lua_State *luastate = luaL_newstate();
luabridge::push(luastate, input.data()); // Supposedly passing a pointer to the first …Run Code Online (Sandbox Code Playgroud) 在 Parsec 或 Megaparsec 解析器中使用 <|> 组合器时,可能需要“尝试”强制回溯,以防第一个解析器在消耗输入后失败。在 Parsec 中,我需要在解析字符串时使用 'try':
?: parse (try (string "abc") <|> string "abd") "" "abd"
正确的“abd”
如果没有 'try',解析会失败,因为第一个解析器消耗了 'a',只留下 'bd' 给第二个解析器,第二个解析器自然也会失败。
在 Megaparsec 中,不需要“尝试”:
?: parse (string "abc" <|> string "abd") "" "abd"
正确的“abd”
因此,在 Megaparsec 中,字符串解析器在失败时不会消耗输入。
我的问题是:
除了实验之外,我怎么会发现 Parsec 和 Megaparsec 之间的字符串解析器行为是不同的——我没有看到它记录在案?
如果解析器失败,我如何轻松地(即,无需实验)判断解析器是否消耗输入?
谢谢你。
我正在尝试使用此库中的 Mutable BasicHashTable:https : //github.com/gregorycollins/hashtables
{-# LANGUAGE GeneralizedNewtypeDeriving #-}
import qualified Data.HashTable.IO as H
import Control.Monad.State.Strict
import Control.Monad.IO.Class (MonadIO)
type A = H.BasicHashTable Int String
newtype MyWrapper a = MyWrapper { runM :: StateT A IO a }
deriving (Functor, Applicative, Monad, MonadIO, MonadState A )
Run Code Online (Sandbox Code Playgroud)
编译器抱怨我尝试A在类型类实例中使用:
error:
• Illegal type synonym family application ‘Control.Monad.Primitive.PrimState
IO’ in instance:
MonadState A MyWrapper
• In the newtype declaration for ‘MyWrapper’
|
10 | deriving (Functor, Applicative, Monad, MonadIO, MonadState …Run Code Online (Sandbox Code Playgroud) 考虑这个 C++ 代码:
struct SomeStruct {
SomeStruct() noexcept;
};
//SomeStruct::SomeStruct() noexcept {}
class SomeClass {
const bool b;
const SomeStruct s;
public:
SomeClass() : b(true) {}
operator bool() const { return b; }
};
void f() {
int *p = new int;
if (SomeClass())
delete p;
}
Run Code Online (Sandbox Code Playgroud)
当我运行clang --analyze -Xanalyzer -analyzer-output=text它时,我得到这个:
q72007867.cpp:20:1: warning: Potential leak of memory pointed to by 'p' [cplusplus.NewDeleteLeaks]
}
^
q72007867.cpp:17:12: note: Memory is allocated
int *p = new int;
^~~~~~~
q72007867.cpp:18:7: …Run Code Online (Sandbox Code Playgroud)
https://youtu.be/brE_dyedGm0?t=1362
data T a where
T1 :: Bool -> T Bool
T2 :: T a
f x y = case x of
T1 x -> True
T2 -> y
Run Code Online (Sandbox Code Playgroud)
Simon 说f可以输入为T a -> a -> a,但我认为返回值必须是 Bool,因为这是 case 表达式分支中的显式结果。这是关于 Haskell GADT 的。为什么会这样呢?
我有以下C程序:
#include <stdio.h>
#include <unistd.h>
void readAndEchoAll(void) {
for(;;) {
char buf[100];
ssize_t size = read(STDIN_FILENO, buf, sizeof(buf));
if(size <= 0) {
return;
}
fwrite(buf, 1, size, stdout);
}
}
int main(void) {
puts("Reading and echoing STDIN until first EOF...");
readAndEchoAll();
puts("Got first EOF. Now reading and echoing STDIN until second EOF...");
readAndEchoAll();
puts("Got second EOF.");
return 0;
}
Run Code Online (Sandbox Code Playgroud)
当我运行它时,它会按照我想要的方式工作。这是它的作用:
Reading and echoing STDIN until first EOF...
asdf
^Dasdf
Got first EOF. Now reading and echoing STDIN until second EOF... …Run Code Online (Sandbox Code Playgroud) 假设我们有一些数据类
{-# LANGUAGE DeriveGeneric, DuplicateRecordFields #-}
import Data.Aeson
import Data.ByteString.Lazy.Char8
import GHC.Generics
data Foo a = Foo { payload :: a }
deriving (Show, Generic)
instance ToJSON a => ToJSON (Foo a)
instance FromJSON a => FromJSON (Foo a)
data Bar a = Bar { payload :: Maybe a }
deriving (Show, Generic)
instance ToJSON a => ToJSON (Bar a)
instance FromJSON a => FromJSON (Bar a)
Run Code Online (Sandbox Code Playgroud)
然后我们尝试解码如下:
*Main > decode $ pack "{}" :: Maybe (Bar String)
Just (Foo …Run Code Online (Sandbox Code Playgroud) Intel CET(控制流执行技术)由两部分组成:SS(影子堆栈)和 IBT(间接分支跟踪)。如果您需要间接地转移到地方,你不能把一个endbr64由于某种原因,你可以抑制IBT单个jmp或call指令用notrack。是否有等效的方法来抑制单个ret指令的SS ?
对于上下文,我正在考虑这将如何与 retpolines 交互,其关键控制流程或多或少类似于push real_target; call retpoline; pop junk; ret. 如果没有办法为此抑制 SS ret,那么在启用 CET 时是否有其他方法让 retpolines 工作?如果没有,我们将有哪些选择?我们是否需要为所有内容维护两组二进制包,一组用于需要 retpolines 的旧 CPU,另一组用于支持 CET 的新 CPU?如果英特尔被证明是错误的,而我们最终仍然需要在他们的新 CPU 上使用 retpolines 呢?我们是否必须放弃 CET 才能使用它们?