How to remove a Aff (similar to Eff's unsafePerformEff)? - purescript

I am trying to get hold of some files content I read from a file via Node.FS.Aff.readTextFile so using asynchrous effects.
However my question is more general.
myFile::forall r. String -> Aff ( fs :: FS | r) (Either Error String)
myFile file = attempt $ readTextFile Node.Encoding.UTF8 file
So I want to get at the Left or Right value. If it where Eff instead of Aff I could use
let x = unsafePerformEff $ myFile "someFile.txt"
Thanks

You should never try to "get at" the value by using unsafePerformEff, as such is truly unsafe and will introduce serious bugs into any larger code base.
Instead, you can use do notation to "get at" the values. For example:
do
result <- attempt $ readTextFile Node.Encoding.UTF8
case result of
Left error -> ...
Right file -> ...
...
Note that there exists no unsafePerformAff, because the computation is asynchronous, and there is no way to block in Javascript runtimes.

Related

Import Fortran unformatted binary

I have an unformatted binary file generated using the Compaq Visual Fortran compiler (big endian).
Here's what the little bit of documentation states about it:
The binary file is written in a general format consisting of data arrays, headed by a descriptor record:
An 8-character keyword which identifies the data in the block.
A 4-byte signed integer defining the number of elements in the block.
A 4-character keyword defining the type of data. (INTE, REAL, LOGI, DOUB, or CHAR)
The header items are read in as a single record. The data follows the descriptor on a new record. Numerical arrays are divided into block of up to 1000 items. The physical record size is the same as the block size.
Attempts to read such data
module modbin
type rectype
character(len=8)::key
integer::data_count
character(len=4)::data_type
logical::is_int
integer, allocatable:: idata(:)
real(kind=8), allocatable::rdata(:)
end type
contains
subroutine rec_read(in_file, out_rec)
integer, intent(in):: in_file
type (rectype), intent(inout):: out_rec
!
! You need to play around with this figure. It may not be
! entirely accurate - 1000 seems to work, 1024 does not
integer, parameter:: bsize = 1000
integer:: bb, ii, iimax
! read the header
out_rec%data_count = 0
out_rec%data_type = ' '
read(in_file, end = 20) out_rec%key, out_rec%data_count,
out_rec%data_type
! what type is it?
select case (out_rec%data_type)
case ('INTE')
out_rec%is_int = .true.
allocate(out_rec%idata(out_rec%data_count))
case ('DOUB')
out_rec%is_int = .false.
allocate(out_rec%rdata(out_rec%data_count))
end select
! read the data in blocks of bsize
bb = 1
do while (bb .lt. out_rec%data_count)
iimax = bb + bsize - 1
if (iimax .gt. out_rec%data_count) iimax = out_rec%data_count
if (out_rec%is_int) then
read(in_file) (out_rec%idata(ii), ii = bb, iimax)
else
read(in_file) (out_rec%rdata(ii), ii = bb, iimax)
end if
bb = iimax + 1
end do
20 continue
end subroutine rec_read
subroutine rec_print(in_recnum, in_rec)
integer, intent(in):: in_recnum
type (rectype), intent(in):: in_rec
print *, in_recnum, in_rec%key, in_rec%data_count, in_rec%data_type
! print out data
open(unit=12, file='reader.data' , status='old')
write(12,*)key
!write(*,'(i5')GEOMINDX
!write(*,'(i5')ID_BEG
!write(*,'(i5')ID_END
!write(*,'(i5')ID_CELL
!write(*,'(i5')TIME_BEG
!write(*,'(i5')SWAT
!format('i5')
!end do
close(12)
end subroutine rec_print
end module modbin
program main
use modbin
integer, parameter:: infile=11
! fixed size for now - should really be allocatable
integer, parameter:: rrmax = 500
type (rectype):: rec(rrmax)
integer:: rr, rlast
open(unit=infile, file='TEST1603.SLN0001', form='UNFORMATTED',
status='OLD', convert='BIG_ENDIAN')
rlast = 0
do rr = 1, rrmax
call rec_read(infile, rec(rr))
if (rec(rr)%data_type .eq. ' ') exit
rlast = rr
call rec_print(rr, rec(rr))
end do
close(infile)
end program main
This code compiles and runs smoothly showing
and produces no errors but this is written in the output file
shows me no useful numerical values
The file in question is available here
And the right WRITE statement should produce a file like this one here
Is my WRITE STATEMENT to output this file type wrong? , and if so, what is the best way?
thank you
The comments above are trying to direct you to one of (at least) two problems in your code. In the subroutine rec_print you have write(12,*)key where you meant to write write(12,*)in_rec%key (at least I think that's what you wanted.)
The other problem I spotted is that rec_print opens reader.data with status='old' and then closes it after writing key. (The use of old here suggests that the file already exists.) Each time rec_print is called, the file is opened, the first record is overwritten, and the file is closed. One solution to this would be to use status='unknown'. position='append', though it would be more efficient to open the file once in the main program and just let the subroutine write to it.
If I make these changes, I get in the data file:
INTEHEAD
GEOMETRY
GEOMINDX
ID_BEG
ID_END
ID_CELL
TIME_BEG
SWAT
A side-comment about CONVERT= and derived types: Your program isn't affected by this, but there are compiler differences with how reading a derived type record with CONVERT= is handled. I think gfortran converts each component according to its type, but I know that Intel Fortran doesn't convert reads (nor writes) of an entire derived type. You are reading individual components, which works in both compilers, so that's fine, but I thought it was worth mentioning.
If you're wondering why Intel Fortran does it this way, it's due to the VAX FORTRAN (where CONVERT= came from) heritage with STRUCTURE/RECORD and the possible use of UNION/MAP (not available in standard Fortran). With unions, there's no way to know how a particular component should be converted, so it just transfers the bytes. I had suggested to the Intel team that this could be relaxed if no UNIONs were present, but that I'm sure is very low priority.

Is it possible to render a component during eval in halogen?

In my halogen project have this eval branch:
eval (SetTest tName next) = do
H.set (State Nothing)
detail <- H.fromAff $ toAff settings $ getTestsByTestname (tName ^. unTestName)
H.set (State (Just detail))
pure next
The toAff bit if off doing AJAX and may take a while to return. In my render function I have
, case ts of
Nothing ->
HH.div [class_ BS.centerBlock]
[HH.i [classes (HH.className <$> ["fa", "fa-spinner", "fa-spin", "loading"])]
[]
]
Just td ->
HH.h3_ [HH.text $ td ^. tdName<<<unTestName]
I'm naively expecting to see a loading spinner when until my aff action returns, but it looks like the eval runs all the way through before the html is rendered. Is this correct?
edit
Turns out this was user error - I was calling my Query in wrong order. Future mes: setting the state does indeed update the ui :-)
No, modifying the state during eval should indeed trigger a render. Unless your Aff isn't really async, I'm not sure why you wouldn't be seeing what you expect here.
Have you tried doing something like H.fromAff $ later' 5000 $ pure <some value>? Where later' comes from Control.Monad.Aff and <some value> is something suitable for detail. You should see the loading spinner for 5 seconds then, before it resolves to <some value>.

Erlang mnesia equivalent of "select * from Tb"

I'm a total erlang noob and I just want to see what's in a particular table I have. I want to just "select *" from a particular table to start with. The examples I'm seeing, such as the official documentation, all have column restrictions which I don't really want. I don't really know how to form the MatchHead or Guard to match anything (aka "*").
A very simple primer on how to just get everything out of a table would be very appreciated!
For example, you can use qlc:
F = fun() ->
Q = qlc:q([R || R <- mnesia:table(foo)]),
qlc:e(Q)
end,
mnesia:transaction(F).
The simplest way to do it is probably mnesia:dirty_match_object:
mnesia:dirty_match_object(foo, #foo{_ = '_'}).
That is, match everything in the table foo that is a foo record, regardless of the values of the fields (every field is '_', i.e. wildcard). Note that since it uses record construction syntax, it will only work in a module where you have included the record definition, or in the shell after evaluating rr(my_module) to make the record definition available.
(I expected mnesia:dirty_match_object(foo, '_') to work, but that fails with a bad_type error.)
To do it with select, call it like this:
mnesia:dirty_select(foo, [{'_', [], ['$_']}]).
Here, MatchHead is _, i.e. match anything. The guards are [], an empty list, i.e. no extra limitations. The result spec is ['$_'], i.e. return the entire record. For more information about match specs, see the match specifications chapter of the ERTS user guide.
If an expression is too deep and gets printed with ... in the shell, you can ask the shell to print the entire thing by evaluating rp(EXPRESSION). EXPRESSION can either be the function call once again, or v(-1) for the value returned by the previous expression, or v(42) for the value returned by the expression preceded by the shell prompt 42>.

Haskell mongodb: Convert Binary value back to ByteString

This is something simple and stupid that I cant just see.
If a new type is defined:
newtype Binary
Constructors
Binary ByteString
Instances:
Eq Binary
Ord Binary
Read Binary
Show Binary
Typeable Binary
Val Binary
How can I deconstruct the Binary value to get the ByteString back?
If I want to save a binary data into mongodb, say a jpg picture, I am able to construct the Val Binary type out of ByteString read from the filesystem. I then insert it into a document.
When I read the data back from the database and take it out of the document I end up with the Binary type and I am sooo stuck with it. I can not get the ByteString type back for use with ByteString.writeFile.
So skipping all the connection stuff the flow is like this:
file <- B.readFile "pic.jpg" -- reading file
let doc = ["file" =: (Binary file)] -- constructing a document to be inserted
run $ insert_ "files" doc -- insert the document
r <- run $ fetch (select [] "files") -- get Either Failure Document back from db
let d = either (error . show) (id ) r -- Get the Document out
let f = at "file" d :: Binary -- Get the data out of the document of type Binary
Thank you.
Assuming your newtype looks like this,
newtype Binary = Binary ByteString
then you can simply pattern match on the constructor to get the ByteString back:
unBinary :: Binary -> ByteString
unBinary (Binary s) = s

stuck with my small code in matlab

I have problem with the following code:
.
.
.
a=zeros(1000,ctimes);
a1=zeros(1000,ctimes);
hold all
for i=num1:num2;
colors=Lines(i);
switch phantom
case 1
path=['E:\filename\'];
path1=['E:\filename2\'];
n=['S',num2str(emt),'_',num2str(i),'.m'];
d=load([path,name]);
a(:,i)=complex(d(:,2),d(:,3)));
n1=['S',num2str(emt),'_',num2str(i),'.m'];
d1=load([path1,name1]);
a1(:,i)=complex(d1(:,2),d1(:,3)));
the problem is that a(:,i) can not be defined. while there is no problem or with complex(d1(:,2),d1(:,3))) , can any expert body help me plz?!
thank you ...
Are you sure you are forming your file name correctly? You are doing something to create a variable n, but using a variable name when you form the path. Here are some recommended debugging steps:
1) make sure the file path is formed correctly:
filePath = fullfile(path, name);
disp(filePath);
The fullfile function concatenates elements of a file path & name, and takes care of using the right file path separator (good for portable code, stops you having to remember to add a / or \ to the end of a file path, etc).
2) check that d is loaded correctly:
clear d;
d = load(filePath);
disp(size(d));
3) check the size of the complex quantity you compute before assigning it to a(:,i):
temp = complex(d(:,2), d(:,3));
disp(size(temp));
By the time you have done these things, you should have found your problem (the dimensions of temp should be [1000 1] to match the size of a(:,i), of course).
As an aside, you should avoid using i as a variable name, especially when you are using complex numbers, since its built-in value is sqrt(-1). Thus, c = a + i * b; would create a complex number (a,b) and put it into c - until you change the meaning of i. A simple solution is to use ii. The same is true for j, by the way. It is one of the unfortunate design decisions in Matlab that you can overwrite built in values like that...