How to convert character to ASCII value in ELM - functional-programming

I'm very new to ELM and I would like to ask, how to convert character into its ASCII value (for example 'A' to 65).

As melpomene said you should use toCode. You will have to import it from the Char library. I made a quick example in Ellie:
https://ellie-app.com/7QyfZLsJza1/1
module Main exposing (main)
import Char exposing (toCode) -- importing toCode ascii conversion from Char
import Html exposing (Html, text)
main : Html msg
main =
text (toString (toCode 'A'))

The documentation is confusing (that's because it is confused), but you can use Char.toCode:
toCode : Char -> Int
Bug report about documentation: https://github.com/elm-lang/core/issues/837
Fix for documentation: https://github.com/elm-lang/core/commit/c81539f41d2ee85ff0df20a35e61bb94ca3c17a9 and https://github.com/elm-lang/core/commit/3a6dc880a475aa153d4ac47156dca5f9a9e892c7

Related

Vector of registers size can not be parametrized by module parameter

I want to use module parameter as a size parameter of Vector, which contains registers, and I try next code:
package Test;
import Vector :: *;
(* synthesize *)
module mkTest #(
parameter UInt#(32) qsize
) (Empty);
Vector#(qsize,Reg#(Bit#(8))) queue <- replicateM (mkReg (0));
endmodule
endpackage
But compiling this module with bsc I get next error message:
Verilog generation
bsc -verilog -remove-dollar Test.bsv
Error: "Test.bsv", line 9, column 11: (T0008)
Unbound type variable `qsize'
bsc version:
Bluespec Compiler (build e55aa23)
If I use not Registers as a type of Vector elements, everything is OK. Next code will produce no errors:
package Test;
import Vector :: *;
(* synthesize *)
module mkTest #(
parameter UInt#(32) qsize
) (Empty);
Vector#(qsize,Bit#(8)) queue = replicate(0);
endmodule
endpackage
And I can not understand, why qsize is Unbound as it is clearly declared as a parameter? If I did something wrong, could you please help me and explain, how to make parameterized size Vector of Regs correctly?
I have asked this question in one of the Bluespec repositories on github and Rishiyur S. Nikhil gave me a very full explanation. See https://github.com/BSVLang/Main/issues/4
In short: Vector as a first parameter needs a type, not UInt (or Int or something else). So the right way to do will be:
Make an interface for module and make it type-polymorphic
Use type from that interface as a Vector size parameter
package Test;
import Vector :: *;
interface Queue_IFC #(numeric type qsize_t);
method Bool done;
endinterface
module mkQueue ( Queue_IFC #(qsize_t) );
Vector #(qsize_t, Reg #(Bit #(8))) queue <- replicateM (mkReg (0));
endmodule
endpackage

How to convert a value to a string?

I am attempting to print a value which is not a string to the console.
In this case it is an array of integers.
How can I convert an array or any other value which allows such behaviour to a string.
module Main where
import Prelude
import Control.Monad.Eff.Console
import Data.Array
main = log [1, 2, 3, 4, 5]
When I run the above the compiler gives the following error:
Could not match type
Array Int
with type
String
while checking that type Array t0 is at least as general
as type String while checking that expression
[ 1, 2, 3, 4, 5 ]
has type String in value declaration main
where t0 is an unknown type
Exactly how you should convert an array to a string depends on what you need to do with that string. That is, it depends on who is going to consume that string and how. The possibilities range from just turning it into a string "array" all the way to binary-base64-encoding.
If all you need is just print it out for debugging or educational purposes, then use the function show from type class Show. There is an instance of that type class defined for arrays, so the function will work in your case.
main = log $ show [1,2,3,4,5]
If you want to take a shortcut, use the function logShow, which does literally the above:
main = logShow [1,2,3,4,5]
An alternative way to print out stuff for debugging purposes is the traceAny function from Debug.Trace. This function doesn't require a Show instance, because it uses the native JavaScript console.log, which will just dump the raw JSON representation of your value:
main = traceAny [1,2,3,4,5] \_ -> pure unit
Beware though: this function is for debugging only, do not use it for reliable output.

Reflection: Struct by string

Let's assume I have this struct with a method:
package main
import (
"fmt"
"reflect"
)
type MyStruct struct {
}
func (a *MyStruct) AAction() {
fmt.Println("Hello a")
}
Now, if I want to call the method "AAction" by string, I can use reflection (this works):
func main() {
reflect.New(reflect.TypeOf(MyStruct{})).MethodByName("AAction").Call([]reflect.Value{})
}
The problem is, that I don't want to use MyStruct{} as an expression, but as a string. Of course this doesn't work:
func main() {
theStruct := "MyStruct"
theAction := "AAction"
reflect.New(reflect.TypeOf(theStruct)).MethodByName(theAction).Call([]reflect.Value{})
}
because reflect.Typeof(theStruct) would be a string.
I tried reading through the documentation, sadly, I can't find anything very useful.
I found this similar question: Call a Struct and its Method by name in Go?
Under the accepted question, the OP asks:
The issue in my case Is I cant not declare t is typed T, its must be some how I can declare t typed T by the name of T is string "T"
which gets answered by
[...] I would suggest to match the name against the string "T" somewhere in your code [...]
which doesn't solve the problem, as I would still need to call MyStruct{} somewhere.
The question is: is there any way to use a struct by giving the name as a string? (without manually mapping the the name of the struct to the struct)
Working version with using reflect.TypeOf(MyStruct{}):
PlayGround
Not working version, obviously calling the method on a string: PlayGround
Sorry, you can't. The answer is: you could not. There is no builtin or pre-initialized registry of type names.
To get started with reflection (reflect package), you need a value (of the type in question). Based on a string (string name of the type), you can't acquire a value of that type, so you can't get started.
If you do want to do what you want only by a string type name, you need to build your own "registry" prior to doing what you want.

How to call sqlite3_open (passing opaque pointers by reference)

As an exercise, I'm trying to create a wrapper for sqlite3. I've got the bridging header set up, and I can see the tool tips for the sqlite3 functions, but I can't figure out how to call sqlite3_open
sqlite3.h contains the following definitions of sqlite3 and sqlite3_open:
typedef struct sqlite3 sqlite3;
SQLITE_API int sqlite3_open(
const char *filename, /* Database filename (UTF-8) */
sqlite3 **ppDb /* OUT: SQLite db handle */
);
Which means that sqlite3_open takes as a trailing parameter a pointer to a pointer to an anonymous structure, which seems clear enough in the tooltip:
func sqlite3_open(filename: CString, ppDb: CMutablePointer<COpaquePointer>) -> CInt
Knowing that CMutablePointer means to pass in &T, the closest I've come is:
class Database {
var handle:COpaquePointer
init(file:String) {
let error = sqlite3_open(file as CString, &handle)
}
deinit {
sqlite3_close(handle)
}
}
There's no error on the sqlite3_close line, so I think I'm at least close, but the sqlite3_open line yields:
Cannot convert the expression's type 'CInt' to type '$T9'
Any clues on how to do this?
Please, no answers that say to use FMDB or other Objective-C based interfaces. As I said, this is at least partially an exercise in figuring out how to use C libraries from swift.
The problem is not with the handle parameter, but with the string conversion. The following works…
class Database {
var handle: COpaquePointer = nil
init(file: NSString) {
let error = sqlite3_open(file.cStringUsingEncoding(NSUTF8StringEncoding), &handle)
}
}
I'm unsure as to why the 'as CString' doesn't work.
When you add #import <sqlite3.h> into Bridging-Header, the sqlite3 C/C++ API will be 'translated' into native swift function. So, the sqlite3_open will be like below.
func sqlite3_open(file:String, inout ppdb:COpaquePointer) -> Int
And you can call this function with "String" type parameter instead of "CString". The swift compiler will translate "String" into UTF8 String data stream automatically.
let error = sqlite3_open(filePath, &db)

What's wrong with groovy math?

This seems quite bizarre to me and totally putting me on the side of people willing to use plain java. While writing a groovy based app I encountered such thing:
int filesDaily1 = (item.filesDaily ==~ /^[0-9]+$/) ?
Integer.parseInt(item.filesDaily) : item.filesDaily.substring(0, item.filesDaily.indexOf('.'))
def filesDaily = (item.filesDaily ==~ /^[0-9]+$/) ?
Integer.parseInt(item.filesDaily) : item.filesDaily.substring(0, item.filesDaily.indexOf('.'))
So, knowing that item.filesDaily is a String with value '1..*' how can it possibly be, that filesDaily1 is equal to 49 and filesDaily is equal to 1?
What's more is that when trying to do something like
int numOfExpectedEntries = filesDaily * item.daysToCheck
an exception is thrown saying that
Cannot cast object '111' with class 'java.lang.String' to class 'int'
pointing to that exact line of code with multiplication. How can that happen?
You're assigning this value to an int:
item.filesDaily.substring(0, item.filesDaily.indexOf('.'))
I'm guessing that Groovy is converting the single-character string "1" into the char '1' and then taking the Unicode value in the normal char-to-int conversion... so you end up with the value 49.
If you want to parse a string as a decimal number, use Integer.parseInt instead of a built-in conversion.
The difference between filesDaily1 and filesDaily here is that you've told Groovy that filesDaily1 is meant to be an int, so it's applying a conversion to int. I suspect that filesDaily is actually the string "1" in your test case.
I suspect you really just want to change the code to something like:
String text = (item.filesDaily ==~ /^[0-9]+$/) ? items.filesDaily :
item.filesDaily.substring(0, item.filesDaily.indexOf('.'))
Integer filesDaily = text.toInteger()
This is a bug in the groovy type conversion code.
int a = '1'
int b = '11'
return different results because different converters are used. In the example a will be 49 while b will be 11. Why?
The single-character-to-int conversion (using String.charAt(0)) has a higher precedence than the integer parser.
The bad news is that this happens for all single character strings. You can even do int a = 'A' which gives you 65.
As long as you have no way of knowing how long the string is, you must use Integer.parseInt() instead of relying on the automatic type conversion.

Resources